Struct in Go
结构体是一种集合类型,可以包含任意个字段。
集合的字段也是变量,可以为字段赋值、对字段取地址。
读取结构体元素用 .
符号;.
也可用在指向结构体的指针上。
type Employee struct {
ID int
Name string
Address string
DoB time.Time
Position string
Salary int
ManagerID int
}
var dilbert Employee
position := &dilbert.Position // 等价于 &(dilbert.Position)
*position = "Senior " + *position
var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"
// 等价于
(*employeeOfTheMonth).Position += " (proactive team player)"
// 结构体和结构体字面量 https://play.golang.org/p/ocySDzIc2Pr
字段顺序不同(每行的顺序,同类型字段是否结合写、结合写的顺序),结构体的类型就不同。
结构体类型 S
里不能定义类型为 S
的字段:集合类型的值(数组类型也是)不能包含自身。
但 S
可以里可以定义类型是 *S
的字段,基于这一点可以实现递归的数据结构(如链表、树)。
结构体的零值有它的每个字段的零值构成。
没有字段的结构体称为空结构体(struct{}
),它占的空间大小是零。
出于效率上的考虑,大结构体类型通常以指针的形式间接地传入函数或从函数返回。
初始化结构体变量可以用简写,简写可以直接用在表达式中:
// shorthand notation
pp := &Point{1, 2}
// equivalent to
pp := new(Point)
*pp = Point{1, 2}
若结构体里的所有字段都可比较,则结构体本身也可比较。
结构体的嵌套机制:将一个具名结构体类型作为另一个结构体类型的匿名字段,提供访问内层字段的语法糖(x.f
代替 x.d.e.f
)。
type Point struct {
X, Y int
}
type Circle struct {
Point
Radius int
}
type Wheel struct {
Circle
Spokes int
}
var w Wheel
w.X = 8 // equivalent to w.Circle.Point.X = 8
w.Radius = 5 // equivalent to w.Circle.Radius = 5
w.Spokes = 20
匿名字段其实有(隐式)名称,名字就是它的具名类型(因此不能有多个同一类型的匿名字段),只是在 .
表达式中可以省略而已,可以省略任意或是全部的匿名字段。
由于匿名字段的名称由它的类型决定,所以匿名字段的可见性也由它的类型决定。
// point 和 circle 是不导出的
w.X = 8 // ok
w.circle.point.X = 8 // forbidden
任何具名类型或指向具名类型的指针都可以用作匿名字段。
使用语法糖的形式时,外层的结构体不光拥有匿名字段,同时获得了匿名字段对应的类型的方法。