1、结构体的基本使用
结构体可以用来声明新的类型,作为其他类型的属性/字段的容器,如下定义一个学生结构体:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 
 | type Person struct {name string
 age int
 }
 
 
 var p1 Person = Person{"lisi", 20}
 
 
 p2 := Person{age:30}
 
 
 p3 := new(Person)
 p3.name = "zs"
 p3.age = 27
 
 
 var p4 Person
 p4.name = "ww"
 p4.age = 30
 
 | 
贴士:
- struct的结构中的类型可以是任意类型,且存储空间是连续的,其字段按照声明时的顺序存放  
- 如果结构体的所有的成员都是可以比较的,那么结构体本身也是可以比较的,使用 == != ,不支持 > 和 <
- 如果结构体的成员要被包外调用,需要大写首字母。
2、结构体地址与实例化
前面说过,对结构体的new其实是生成了一个指针类型。其实对结构体进行&取地址操作时,也可以视为对该类型进行一次new的实例化操作。
| 12
 3
 4
 
 | ins := &T{}
 # T是结构体类型
 # ins为结构体的实例,类型为*T,是指针类型
 
 | 
3、内嵌结构体
当前结构体可以直接访问其内嵌结构体的内部字段:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 
 | package main
 import "fmt"
 
 type Animal struct {
 Age int
 }
 
 type Person struct {
 Animal
 Name string
 }
 
 type Student struct {
 Person
 ClassName string
 }
 
 func main() {
 
 
 s1 := Student{
 Person{
 Animal: Animal {
 Age: 15,
 },
 Name:"lisi",
 },
 "一班",
 }
 fmt.Println(s1.Age)
 fmt.Println(s1.Person.Name)
 
 
 var s2 Student
 s2.Name = "zs"
 s2.Age = 30
 s2.ClassName = "二班"
 fmt.Println(s2.Age)
 fmt.Println(s2.Person.Name)
 }
 
 | 
4、匿名字段
结构体的字段名与类型一一对应,如果不提供名字,则为匿名字段。
匿名字段如果是一个struct,这个struct拥有的全部字段都被隐式引入了当前的struct。
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | type Person struct {name string
 age int
 }
 
 type Student struct {
 Person
 classroom string
 }
 
 | 
不仅仅是struct,其他所有内置类型和自定义类型都可以作为匿名字段:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 
 | package main
 import "fmt"
 type Person struct {
 name string
 age int
 }
 
 type course []string
 
 type Student struct {
 Person
 course
 classroom string
 }
 
 func main() {
 
 
 s := Student{Person:Person{"LiLei", 17}, classroom:"二班"}
 
 
 fmt.Println("name = ", s.name)
 fmt.Println("classroom =  ", s.classroom)
 
 
 s.course = []string{"语文", "美术"}
 fmt.Println("course = ", s.course)
 }
 
 | 
贴士:如果Person和Student中都有同一个字段,那么Go会优先访问当前层。例如二者都有tel字段,那么s.tel将会访问的是Student中的数据。