Definition

一个结构体(struct)就是一个字段的集合.
成员相同但定义顺序不同的结构体是不同的类型.
一个命名为 S 的结构体类型将不能再包含 S 类型的成员: 因为一个聚合的值不能包含它自身(该限制同样适用于数组). 但 S 类型的结构体可以包含 *S 指针类型成员, 这可以让我们创建递归的数据结构.
通常会将结构体成员的零值作为最合理的默认值.
如果考虑效率的话, 较大的结构体通常用指针的方式传入函数或自函数返回.
如果结构体内的全部成员都是可比较的. 那么这个结构体就是可比较的.
空结构体类型不占内存空间, 但是具有结构体的一切属性. 当我们需要使用结构体而又不需要具体属性时可以使用它. 如用于通道间传递 “信号”.

结构体操作:

  1. type Vertex struct {
  2. X int
  3. Y int
  4. }
  5. func main() {
  6. v := Vertex{1, 2}
  7. v.X = 4
  8. p := &v
  9. p.X = 5 // 使用 p.X 取代 (*p).X
  10. v = Vertex{X: 1} // 只为指定字段赋值
  11. fmt.Println(v.X)
  12. }

匿名成员

Go 语言规范规定, 如果一个字段的声明中只有字段的类型名而没有字段的名称, 那么它就是一个嵌入字段, 也被称为匿名字段或匿名成员(这种声明方法相当于静态导入).
匿名成员的数据类型必须是命名的类型或指向一个命名的类型指针.
可通过嵌入匿名的结构体实现类型的扩展. 匿名的结构体字段会将其类型上的字段和方法添加到其所在结构体之上.
如果嵌入类型的方法和所属结构体中的方法冲突(只要方法的名称相同, 无论他们的签名是否一致), 同名的被嵌入类型的方法都会被所属结构体中的方法覆盖掉. 属性亦是如此.
如果处于同一层级的多个嵌入字段拥有同名的字段或方法, 则会引发编译错误.
得益于匿名嵌入的特性, 我们可以直接访问叶子属性而不需要给出完整的路径:

// 匿名成员
type Point struct {
    X, Y int
}
type Circle struct {
    Point
    Radius int
}
type Wheel struct {
    Circle
    Spokes int
}
func main() {
    var w Wheel
    w.X = 1 // 相当于 w.Circle.Point.X = 1
}