在结构体中若是一个字段声明只有类型而没有指定名称,则这个字段叫作匿名字段。匿名字段的类型必须由一个数据类型的名称(好比int、string、Sortable等)或者一个非接口类型对应的指针类型的名称(好比*string、*p.T等)表明。更重要的是,表明匿名字段类型的非限定名称将被隐含地做为该字段的名称,如:ide
type Sequence struct{spa
len int指针
cap int排序
Sortable 接口
sortableArray sort.Interface编译器
}string
其中字段Sortable只有类型没有指定名称,它就是匿名字段,go编译器缺省把Sortable做为它的名字,即上述定义等价于:it
type Sequence struct{编译
len inttable
cap int
Sortable Sortable
sortableArray sor.Interface
}
若是匿名字段类型是一个指针类型的话,那么这个指针类型所指的数据类型的非限定名称会做为该字段的名称,即:
type Anonymities struct{
T1
*T2
P.T3
*P.T4
}
该结构体类型包含了4个匿名字段,其中T1和P.T3为非指针的数据类型,它们隐含的名称分别为T1和T3; 而*T2和*P.T4为指针类型,它们隐含的名称分别为T2和T4。
这里也变相地解释了什么是非限定表示符?
非限定标识符指的是不包含代码包名称和点“.”的标识符。
另外,即使是匿名的名称也不能与结构体内的其余字段名称重复。
结构体类型中的嵌入字段比接口类型间的嵌入有着更加复杂的含义。嵌入类型所附带的方法都会无条件地与被嵌入的结构体类型关联在一块儿,即它们也成为了被嵌入的结构体类型的方法。
这意味着,结构体类型自动地实现了它包含的全部嵌入类型所实现的接口类型。
// 定义一个接口
type Sortable interface{
sort.Interface
Sort()
}
// 定义一个结构体
type Sequence struct{
Sortable
sorted bool
}
其中存储和操做可排序序列的功能都交给了匿名字段Sortable,而后又定义了一个bool类型的字段sorted,并用它表示排序序列是否已经被排序。
此时若是咱们有一个Sequence类型的值seq,那么就能够直接在这个值上调用Sortable接口类型中包含的那些方法了,如seq.Sort(),在这种状况下,嵌入类型Sortable的Sort()方法被隐藏了。
被隐藏带来一些便利——能够方便地声明一个同名方法,同时不丢弃原有功能:
func (s *Sequence) Sort() {
s.Sortable.Sort() // 不丢弃原有能力
s.sorted = true // 添加新能力
}
注意,若是这两个Sort()方法的名称相同但签名不一样,那么嵌入类型Sortable的方法Sort()就被隐藏了,这时在Sequence的类型值上调用Sort()方法的时候,就必须依据被该类型的Sort()方法的签名来编写调用表达式。