2 回答

TA貢獻1921條經驗 獲得超9個贊
正如 Go 規范所說,類型 T 的方法集由接收器類型為 T 的所有方法組成,而對應指針類型 *T 的方法集由接收器類型為 *T 或 T 的所有方法組成。 這意味著 *T 的方法集包括 T 的,但不包括相反的。
出現這種區別是因為如果接口值包含指針 *T,則方法調用可以通過取消引用指針來獲取值,但是如果接口值包含值 T,則方法調用沒有安全的方法獲取指針。(這樣做將允許方法修改接口內的值的內容,這是語言規范所不允許的。)
即使在編譯器可以將值的地址傳遞給方法的情況下,如果方法修改了值,則更改將在調用者中丟失。例如,如果 bytes.Buffer 的 Write 方法使用值接收器而不是指針,則此代碼:
var buf bytes.Buffer io.Copy(buf, os.Stdin)會將標準輸入復制到 buf 的副本中,而不是復制到 buf 本身中。這幾乎從來都不是理想的行為。

TA貢獻1836條經驗 獲得超13個贊
如果您有 a
T
并且它是可尋址的,您可以調用接收器類型*T
為 的方法以及接收器類型為T
的方法,因為方法調用t.Meth()
將等效于(&t).Meth()
( Calls )。如果您有 a
T
并且它不可尋址(例如,函數調用的結果,或索引到映射的結果),Go 無法獲得指向它的指針,因此您只能調用具有 a 的方法的接收器類型T
,不是*T
。如果您有一個接口
I
,并且I
的方法集中的部分或全部方法由接收器為 的方法提供*T
(其余方法由接收器為 的方法提供T
),則*T
滿足接口I
,但T
不滿足。那是因為*T
的方法集包括T
's,但不是相反的(再次回到第一點)。
簡而言之,您可以混合和匹配帶有值接收器的方法和帶有指針接收器的方法,并將它們與包含值和指針的變量一起使用,而不必擔心哪個是哪個。兩者都可以使用,并且語法相同。然而,如果需要帶有指針接收器的方法來滿足接口,那么只有一個指針可以分配給接口——一個值將是無效的。
- 2 回答
- 0 關注
- 167 瀏覽
添加回答
舉報