Go中的struct

532 阅读3分钟

这是我参与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来创建. 即可以按顺序初始化结构体中的值, 又可以给指定的字段指定初始值. 可以递归嵌套, 可以有匿名字段, 多种多样的定义和使用方式, 用上了就爱上了!!!