Struct types
结构体是一系列命名元素组成,每一个元素称之为一个字段,它有自己的类型跟名称。字段名称可以显式指定(IdentifierList) 或者隐式指定 (EmbeddedField)。结构体内部,非空 的字段必须是 唯一的。
StructType = "struct" "{" { FieldDecl ";" } "}" .
FieldDecl = (IdentifierList Type | EmbeddedField) [ Tag ] .
EmbeddedField = [ "*" ] TypeName .
Tag = string_lit .
// 空结构体
struct {}
// 6 个字段的结构体
struct {
x, y int
u float32
_ float32 // 填充字段
A *[]int
F func()
}
一个有类型但是没有字段名称的字段称为 *内嵌字段,内嵌字段需要指定一个类型名T
或者是一个指针指向一个非接口类型 **T
, T
自己也不能是一个接口类型,这个类型名称会被当成这个字段的名称。
// 一个拥有四个字段且类型为 T1, *T2, P.T3 和 *P.T4 的结构体
struct {
T1 // 字段名称是 T1
*T2 // 字段名称是 T2
P.T3 // 字段名称是 T3
*P.T4 // 字段名称是 T4
x, y int // 字段名称是 x 和 y
}
下面的声明是非法的,因为字段名称在结构体当中必须是唯一的:
struct {
T // 跟字段 *T 和 *P.T 冲突
*T // 跟字段 T 和 *P.T 冲突
*P.T // 跟字段 T 和 *T 冲突
}
结构体 x
里的内嵌字段的字段或者 方法 称为promoted , 如果 x.f
是一个合法的 选择器 ,它代表了这个字段或者方法 f
。
升级字段跟普通字段没什么差别,除了它不能被用于结构体中 复合字段 的字段名称。
对于一个结构体 S
和一个 声明类型 T
, 升级字段被包含在这个结构体的方法体当中:
- 如果
S
包含了内嵌字段T
, 则S
的 方法集 和*S
都包含了带有接收器T
的升级字段。*S
的方法集也包含了带有接收器*T
的升级字段。 - 如果
S
包含了内嵌字段*T
,S
的方法集跟*S
都会包含带有接受体T
或者*T
的升级字段。
字段的声明可能会附带一个可选的字符串 标签,这个会成为对应字段的属性。一个空的标签等价于没有标签,它可以通过 反射接口 表现出来并作为 类型标识 ,否则会被忽略。
struct {
x, y float64 "" // 空的标签等价于没有标签
name string "any string is permitted as a tag"
_ [4]byte "ceci n'est pas un champ de structure"
}
// 一个对应时间戳的 protocol buffer 的结构体。
// 标签表示 protocol buffer 字段序号;
// 它们遵循反射包的约定。
struct {
microsec uint64 `protobuf:"1"`
serverIP6 uint64 `protobuf:"2"`
}
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。