这是我参与8月更文挑战的第10天,活动详情查看:8月更文挑战
struct
结构体是复合类型, 是值类型, 可以通过new函数来创建, 返回结构体指针
由一系列的字段组成, 每个字段有自己的类型和字段名, 字段名遵循可见性规则
格式
type 结构体类型名称 struct {
字段名1 类型名1
字段名2 类型名2
}
定义结构体
// 定义一个结构体
type Person struct {
// 字段1
name string `名字`
// 字段2
age int `年龄`
}
结构体的创建
// 不写字段名, 按字段名顺序进行赋值, 一一对应
p1 := Person{"shaosiming", 18}
fmt.Println(p1)
// 写字段名, 可以不按顺序进行赋值
p2 := Person{age: 20, name: "dasiming"}
fmt.Println(p2)
// 使用new函数创建结构体, 返回一个结构体指针, 并将结构体中的各个字段置为零值
p3 := new(Person)
fmt.Println(p3)
结构体的访问
// 结构体变量名.字段名
p4 := Person{"shaosiming", 18}
fmt.Println(p4.name)
fmt.Println(p4.age)
结构体中的标签
结构体中的每个字段, 除了可以有名字和类型外, 还可以有标签tag, 这个标签是一个字符串.
结构体中的标签可以通过reflect来获取
// 定义一个结构体
type Person struct {
// 字段1
name string `名字`
// 字段2
age int `年龄`
}
// 结构体中的标签
nameTag := reflect.TypeOf(p4).Field(0).Tag
ageTag := reflect.TypeOf(p4).Field(1).Tag
fmt.Println(nameTag)
fmt.Println(ageTag)
递归嵌套
// 不能嵌入自身的类型, 要嵌入自身的指针类型
type Node struct {
last *Node
next *Node
}
结构体嵌套(聚合)
type Teacher struct {
teacherName string
TeacherNum int
car Car
}
type Car struct {
carBrand string
carColor string
}
// 结构体嵌套
teacher := Teacher{car: Car{"four circle", "black"}, teacherName: "shaosiming", TeacherNum: 001}
fmt.Println("老师工号: ", teacher.TeacherNum)
fmt.Println("都是名字: ", teacher.teacherName)
fmt.Println("老师小汽车品牌: ", teacher.car.carBrand)
fmt.Println("老师小汽车颜色: ", teacher.car.carColor)
匿名字段
// 匿名字段
s1 := Student{School{"Tsinghua", "五道口"}, "shaosiming", 18, 180}
fmt.Println(s1)
// 访问结构体中匿名字段中的数据
// 匿名字段的类型, 可以染成匿名字段名, 然后进行访问
fmt.Println(s1.School.schoolName)
fmt.Println(s1.School.addr)
// 也可以直接访问匿名字段中的字段名
fmt.Println(s1.schoolName)
fmt.Println(s1.addr)
fmt.Println(s1.name)
fmt.Println(s1.age)
// 如果匿名字段不是复合类型, 可以直接.匿名字段类型名
fmt.Println(s1.float64)
匿名字段中的同名字段
type Owner struct {
// 当两个匿名字段中, 由同名字段时, 要使用: 匿名字段类型名.字段名
Dog
Book
}
type Book struct {
name string
}
type Dog struct {
name string
}
owner := Owner{Dog{"come blessing"}, Book{"Three Body"}}
fmt.Println(owner)
// 当一个结构体内嵌了多个匿名结构体字段, 并且它们中有同名字段, 在访问的时候
// 要指名匿名字段类型名即: Dog.name, Book.name
fmt.Println(owner.Book.name)
fmt.Println(owner.Dog.name)
总结
Go中的结构体: 可以指定结构体中字段的标签. 有多种创建方式, 可以使用{}来创建, 也可以使用new来创建. 即可以按顺序初始化结构体中的值, 又可以给指定的字段指定初始值. 可以递归嵌套, 可以有匿名字段, 多种多样的定义和使用方式, 用上了就爱上了!!!