go结构体指针
package main
import (
"fmt"
)
type User struct{
Username string
Sex string
Age int
AvatarUrl string
}
func initUser1() {
var user *User
fmt.Printf("user=%#v\n",user) // user=(*main.User)(nil) 指针没有初始化是nil
var user01 *User = &User{}
user01.Age = 19 // 指针类型 实际是这样的,(*user01).Age go做了一个语法糖,把(*user01).Age 简写成user01.Age
user01.Username = "user01"
(*user01).Sex = "女"
// user01.Age = 19
fmt.Printf("initUser1 user01=%#v\n",user01)
fmt.Printf("user01.username=%s age=%d sex=%s avatar=%s\n",user01.Username,user01.Age,user01.Sex,user01.AvatarUrl)
var user02 *User = &User{
Username :"user02",
Age :20,
}
fmt.Printf("user02=%#v\n",user02)
fmt.Printf("user02.username=%s age=%d sex=%s avatar=%s\n",user02.Username,user02.Age,user02.Sex,user02.AvatarUrl)
var user03 *User = new(User) //指针类型的必须要初始化分配内存才行 用new或者&User
user03.Username = "user03"
user03.Age = 19
fmt.Printf("user03=%#v\n",user03)
fmt.Printf("user03.username=%s age=%d sex=%s avatar=%s\n",user03.Username,user03.Age,user03.Sex,user03.AvatarUrl)
}
func main() {
initUser1()
}
输出:
user=(*main.User)(nil)
initUser1 user01=&main.User{Username:"user01", Sex:"女", Age:19, AvatarUrl:""}
user01.username=user01 age=19 sex=女 avatar=
user02=&main.User{Username:"user02", Sex:"", Age:20, AvatarUrl:""}
user02.username=user02 age=20 sex= avatar=
user03=&main.User{Username:"user03", Sex:"", Age:19, AvatarUrl:""}
user03.username=user03 age=19 sex= avatar=
package main
import (
"fmt"
"unsafe"
)
type Person struct{
name string
sex byte
age int
}
func testStruct(){
// 1.顺序初始化,必须全部初始化完整
var man Person = Person{ name: "andy",sex: 'm', age: 18}
fmt.Println( "man:", man)
// 2.部分初始化
man2 := Person{sex:'f', age :19}
fmt.Println( " man2: ", man2)
//索引成员变量“.”
fmt.Printf( "man2.name = %q\n", man2.name)
var man3 Person
man3.name = "mike"
man3.sex = 'm'
man3.age = 99
fmt.Println( "man3 : ", man3)
man3.age = 1073
fmt.Println( "man3 : ", man3)
}
func compareStruct(){
//结构体比较
var p1 Person = Person{name: "andy", sex: 'm', age: 18}
var p2 Person = Person{ name: "andy", sex: 'm', age: 18}
var p3 Person = Person { name: "andy", sex: 'm', age: 181}
fmt.Println( "p1 == p2 ?", p1 == p2)
fmt.Println("p1 == p3 ?", p1 == p3)
}
func passValueStruct(man Person) {
fmt.Println( "002 passValueStruct temp size:", unsafe.Sizeof(man))
man.name = "name1"
man.age = 33
fmt.Println( "01test: man", man)
fmt.Println( "003 temp size:", unsafe.Sizeof(man))
}
func pointStruct(){
var p1 *Person = &Person { name: "n1",sex: 'f', age: 19}
fmt.Println( "p1", p1)
var p2 = new(Person)
p2 = &Person { name: "n2",sex: 'f', age: 20}
fmt.Println("p2",p2)
var tmp = Person{ name: "n3",sex: 'f', age: 21}
var p3 *Person
p3 = &tmp
fmt.Println("p3",p3)
var p4 = new(Person)
p4.name = "n4"
p4.age = 22
p4.sex = 'f'
fmt.Println("p4",p4)
//结构体指针变量的地址==结构体首个元素的地址.
fmt.Printf( "p3 = %p \n", p3)
fmt.Printf( "&p3.name = %p \n", &p3.name)
}
func test2(p *Person){
fmt.Println( "test2:", unsafe.Sizeof(p))
p.name = "Luffy"
p. age = 779
p.sex = 'm'
}
func initStruct(){
var temp =Person{}
fmt.Println( "main temp size:", unsafe.Sizeof(temp))
fmt.Println( "00temp", temp)
passValueStruct(temp) //值传递。将实参的值拷贝一份给形参。
fmt.Println( "02temp", temp)
//结构体变量的地址==结构体首个元素的地址。
fmt.Printf( "&tmp = %p \n", &temp)
fmt.Printf( "&temp.name = %p \n", &temp.name)
//unSafe.Sizeof(变量名) ——>此种类型的变量所占用的内存空间大小
fmt.Println( " main temp size:", unsafe.Sizeof( true))
}
func swapTest(){
/*结构体指针传参:
unSafe.Sizeof(指针)︰不管何种类型的指针,在64位操作系统下,大小一致。均为8字节!!!
将结构体变量地址值,传递(传引用)。 —— 使用频率非常高! ! !*/
p3 := new(Person)
p3.name = "n3"
p3.age = 22
p3.sex = 'f'
fmt.Printf( "p3, type= %T\n", p3)
fmt.Println( "p3:", p3)
fmt.Println( "main:", unsafe.Sizeof(p3))
test2(p3)
fmt.Println( "p3:", p3)
}
func main(){
testStruct()
compareStruct()
initStruct()
pointStruct()
swapTest()
}
输出:
man: {andy 109 18}
man2: { 102 19}
man2.name = ""
man3 : {mike 109 99}
man3 : {mike 109 1073}
p1 == p2 ? true
p1 == p3 ? false
main temp size: 32
00temp { 0 0}
002 passValueStruct temp size: 32
01test: man {name1 0 33}
003 temp size: 32
02temp { 0 0}
&tmp = 0xc000004500
&temp.name = 0xc000004500
main temp size: 1
p1 &{n1 102 19}
p2 &{n2 102 20}
p3 &{n3 102 21}
p4 &{n4 102 22}
p3 = 0xc000004620
&p3.name = 0xc000004620
p3, type= *main.Person
p3: &{n3 102 22}
main: 8
test2: 8
p3: &{Luffy 109 779}
说明:
type Person struct{
name string
sex string
age int
}
普通变量定义和初始化:
1.顺序初始化:依次将结构体内部所有成员初始化。
var man Person = Person{"andy", 'm',20}
2.指定成员初始化:
man := Person{name:"rose", age:18} ----未初始化的成员变量,取该数据类型对应的默认值
普通变量的赋值和使用:
使用“.”索引成员变量。
var man3 Person
man3.name = "mike"
man3.sex = 'm'
man3.age = 99
结构体变量的比较和赋值:
1. 比较:只能使用==和!=不能> < >= <=
2. 相同结构体类型(成员变量的类型、个数、顺序—致)变量之间可以直接赋值。
结构体地址:
结构体变量的地址==结构体首个元素的地址。
结构体传参:
unSafe.Sizeof(变量名) ——>此种类型的变量所占用的内存空间大小
将结构体变量的值拷贝一份,传递。 ——几乎不用。内存消耗大,效率低。
指针变量定义和初始化:
1. 顺序初始化:依次将结构体内部所有成员初始化。
var man *Person = &Person{"andy", 'm', 20}
2. new(Person)
指针索引成员变变量:
使用“.”索引成员变量。
var man3 Person
man3.name = "mike"man3.sex = 'm'
man3.age = 99
结构体地址:
结构体指针变量的地址==结构体首个元素的地址.
结构体指针传参:
unSafe.Sizeof(指针)︰不管何种类型的指针,在64位操作系统下,大小一致。均为8字节!!!
将结构体变量地址值,传递(传引用)。 —— 使用频率非常高! ! !
练习:
定义一个结构体,包含成员string、int、bool、[]string.
在main函数中定义结构体“普通变量”,不初始化。封装函数initFunc,在该函数内初始化,main函数中打印查看。
结构体指针做函数返回值:
不能返回局部变量的地址值。---- 局部变量保存栈帧上,函数调用结束后,栈帧释放。局部变量的地址不再受系统保护,随时可能分配给其他程序.
可以返回局部变量的值。
package main
import "fmt"
type Person3 struct {
name string
age int
flg bool
intereset []string
}
func initFunc(p *Person3){
p.name = "Nami"
p.age = 18
p.flg = true
p.intereset = append(p.intereset, "shopping")
p.intereset = append(p.intereset, "sleeping")
}
//通过函数返回值,初始化结构体。
func initFunc2() *Person3{
p := new(Person3)
p.name = "Nami"
p.age = 18
p.flg = true
p.intereset = append(p.intereset, "shopping")
p.intereset = append(p.intereset, "sleeping")
return p
//不能返回局部变量的地址值。---- 局部变量保存栈帧上,函数调用结束后,栈帧释放。局部变量的地址不再受系统保护,随时可能分配给其他程序。
//return *p
}
func main() {
var person Person3
fmt.Println( "00 person:", person)
initFunc(&person)
fmt.Println( "01 person:", person)
p4 := initFunc2()
fmt.Println(p4)
}
输出:
00 person: { 0 false []}
01 person: {Nami 18 true [shopping sleeping]}
&{Nami 18 true [shopping sleeping]}
go 结构体实例出来的对象,是值类型,对应直接指向一个内存空间(这个内存空间也有一个自己的内存地址),赋值时,直接将默认类型值改为赋值; 不同于引用类型是>> 引用类型是你要先指向一个地址,然后那个地址又指向另一个内存空间
写入自己的博客中才能记得长久