package main
import("fmt")//定义一个Cat结构体,将Cat的各个字段/属性信息放入到Cat结构体中进行管理//在创建一个结构体变量后,如果没有给字段赋值,都对应一个默认值//指针、slice、map的零值都是nil,即没有分配空间type Cat struct{
Name string
Age int
Color string
Hobby string}funcmain(){//创建一个Cat变量var cat1 Cat
cat1.Name ="小白"
cat1.Age =3
cat1.Color ="白色"
cat1.Hobby ="吃鱼"
fmt.Println(cat1)
fmt.Printf("%p\n",&cat1)
fmt.Printf("%p\n",&cat1.Name)
fmt.Printf("%p\n",&cat1.Age)//结构体是一种自定义数据类型,代表一类事物//结构体变量(实例)是具体的实际的,代表一个具体变量//结构体为值引用}
创建结构体实例的四种方式
package main
import("fmt")type Person struct{
Name string
Age int}funcmain(){//创建结构体变量和访问结构体字段//方式一//直接声明//方式二
p2 := Person{"tom",18}//p2.Name = "tom"//p2.Age = 18
fmt.Println(p2)//方式三
p3 :=new(Person)//等效于var p3 *Person = new(Person)//p3为一个指针//go的设计者为了程序员使用方便,底层会对p3.Name = "john"进行处理//会给p3加上取值运算符 (*p3).Name = "john"(*p3).Name ="smith"
p3.Name ="john"(*p3).Age =10
p3.Age =18
fmt.Println(*p3)//方式四//person是一个指针var person *Person =&Person{"mary",20}}
结构体使用细节
package main
import("fmt")//结构体的所有字段在内存中都是连续的//结构体时用户单独定义的的类型//和其他类型进行转换时需要有完全相同的字段(名字、个数和类型)//结构体进行type重新定义(相当于取别名)Golang认为是新的数据类型//但是相互之间可以强转//struct的每个字段上可以写一个tag//tag可以通过反射机制获取//常见的使用场景是序列化和反序列化type Point struct{
x int
y int}type Rect struct{
leftUp,rightDown Point
}type Rect2 struct{
leftUp,rightDown *Point
}funcmain(){
r1 := Rect{Point{1,2},Point{3,4}}//r1有四个int,在内存中是连续分布的
r2 := Rect2{&Point{10,20},&Point{30,40}}//r2有两个*Point类型,这两个*Point类型本身的地址也是连续的//但是它们指向的地址不一定是连续的//需要看系统在运行时如何分配}