在結構體中若是一個字段聲明只有類型而沒有指定名稱,則這個字段叫作匿名字段。匿名字段的類型必須由一個數據類型的名稱(好比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()方法的簽名來編寫調用表達式。