2 回答

TA貢獻1820條經驗 獲得超10個贊
一個類型可能有一個與之關聯的方法集。接口類型的方法集就是它的接口。任何其他類型 T 的方法集由所有用接收器類型 T 聲明的方法組成。對應指針類型 *T 的方法集是用接收器 *T 或 T 聲明的所有方法的集合(即它還包含該方法T 組)。進一步的規則適用于包含嵌入字段的結構,如結構類型部分所述。任何其他類型都有一個空方法集。在方法集中,每個方法必須有一個唯一的非空方法名稱。
如果 xf 是表示該字段或方法 f 的合法選擇器,則稱為提升結構 x 中嵌入字段的 字段或方法 f。
...
給定一個結構類型 S 和一個定義類型 T,提升的方法包含在結構的方法集中,如下所示:
If S contains an embedded field T, the method sets of S and *S both include promoted methods with receiver T. The method set of *S also includes promoted methods with receiver *T.
如果 S 包含嵌入字段 *T,則 S 和 *S 的方法集都包含帶有接收器 T 或 *T 的提升方法。

TA貢獻1841條經驗 獲得超3個贊
如果m為類型定義了方法T,則該方法對T和都可用*T:
type T struct {}
func (t T) m() {}
func main() {
t:=T{}
tp:=&T{}
t.m() // valid: m defined for T
tp.m() // valid: m defined for *T
}
如果一個方法是用指針接收器定義的,它只被定義為*T而不是為T':
func (t *T) n() {}
func main() {
t:=T{}
tp:=&TP{
t.n() // Valid: &t is passed to n
tp.b // valid
mp:=map[int]T{1:t}
mp[1].n() // not valid. mp[1] is not addressable
pp:=map[int]*T{1:&t}
pp[1].n() // valid: pp[1] is *T
}
這樣做的原因很簡單:它可以防止無意中修改副本而不是縮進對象。如果帶有指針接收器的方法也可用于值類型,則使用以下代碼:
mp[1].n()
n,采用指針接收器,將修改 的值的副本mp[1],而不是存儲在 的值mp[1]。具有指針接收器的方法不可用于值類型的事實阻止了這一點,這將成為編譯錯誤,因為n沒有為 定義T,并且mp[1]不可尋址,從而阻止了編譯器將值轉換為指針。
- 2 回答
- 0 關注
- 134 瀏覽
添加回答
舉報