php小編百草對於 Go 官方指南中關於所有方法使用相同類型接收器的建議感到困惑。在學習 Go 語言過程中,我們經常會遇到這樣的建議,在方法定義時,接收器的類型應該保持一致。然而,這個建議在實際應用上會帶來一些疑問。為了更好地理解這個建議的含義和用途,我們將對其進行深入探討,並嘗試找到合理的解釋。
我試圖透過官方的 Go 教學來學習 Go,我發現關於值與指標接收器的部分的最後部分令人困惑:
一般來說,給定類型上的所有方法都應該具有值接收器或指標接收器,但不能同時具有兩者。 (我們將在接下來的幾頁中了解原因。)
基本上,我有兩個問題:
A)我似乎找不到為什麼我們不應該在本章的其餘部分混合使用兩種類型的接收器的原因,因此如果有人可以解釋或引用討論此問題的部分,我將不勝感激。
B) 假設混合使用指標和值接收器確實是一個壞主意,那麼如何實作不同的介面呢?例如,我發現該教程描述了兩個不同的內建接口,即 Stringer
和 error
。在為 Stringer
提供的程式碼中,使用了值接收器,並且切換到指標接收器似乎不起作用,而在 error
介面中,使用了指標接收器。如何在不違反上述原則的情況下為結構實現這兩個介面。
請注意,我已經研究過類似的問題,涉及使用值接收器與指標接收器的缺點(例如物件創建),以及保持一致性的重要性(來自這個問題),但因為我是一個真正的初學者對於Go,我只是嘗試將這些內容與官方Go 之旅中的信息/示例結合起來。
謝謝!
對於第一個問題,同時擁有值接收器和指標接收器可能會導致微妙的競爭,因為值接收器會複製物件。例如:
type T struct { field int } func (T) ValueReceiver() int {return 1} func (t *T) SetField(i int) {t.field=i}
在上面的範例中,如果您同時呼叫 SetField
和 ValueReceiver
,則您將進行一場競賽。這是因為,當 SetField
寫入欄位時,ValueReceiver
正在建立接收器的副本,導致在沒有任何明確同步的情況下讀取相同欄位。
對於第二個問題:如果您有修改 T
的方法,那麼讓所有方法都使用指標接收器是有意義的。這樣您就可以防止微妙的競爭,並實作 T
的所有介面。
這是有關此主題的常見問題解答的連結(感謝@jub0bs):
https://www.php.cn/link/bcc097feafe80f489ef54b0720ca059c
#此範例基於以下帖子:
https://dave.cheney .net/2015/11/18/wednesday-pop-quiz-spot-the-race
#以上是對 Go 官方指南中關於所有方法使用相同類型接收器的建議感到困惑的詳細內容。更多資訊請關注PHP中文網其他相關文章!