簡體   English   中英

為什么帶有指針接收器的方法在接收值時仍然可以工作?

[英]Why does a method with a pointer receiver still work when it receives a value?

我只是在環游世界中練習51練習 解釋聲稱Scale方法在接收到Vertex而不是指向Vertex的指針時無效。

然而,當我改變聲明v := &Vertex{3, 4}v := Vertex{3, 4}main輸出唯一的變化是缺失&來標記指針。

那么,即使變量不是指針,為什么Scale也會更改它收到的變量?

它不會“接收”值。 Go是強類型的,因此,如果在某處指定了指向T的指針,則指向T( *T )的指針是唯一可以作為該類型位置的值出現的選項。

在編譯器中,“魔術”可以在某些條件下有效地“重寫”您的代碼:

如果x的方法集包含m並且可以將參數列表分配給m的參數列表,則方法調用xm()是有效的。 如果x是可尋址的並且&x的方法集包含m ,則xm()(&x).m()簡寫:

相關: 方法集

游覽建議的區別實際上不是將v := &Vertex{3, 4}更改為v:= Vertex{3, 4} ,而是更改了這兩種方法的定義,以便它們使用值而不是值指針。 因此,例如,對於Scalefunc (v *Vertex) Scale(f float64) {...變為func (v Vertex) Scale(f float64) {... (請注意(v *Vertex) ,一個指針值,變為(v Vertex) ,一個非指針值)。 在這兩種情況下,都應將v的聲明保留為v := &Vertex{3, 4}

您會注意到,在第一種情況下,當方法使用指針時,輸出為&{15 20} 25 但是,當方法采用值而不是指針時,輸出為&{3 4} 5

在這兩種情況下, v都是指向Vertex對象的指針。 在第一種情況下,將指針傳遞給方法,並且一切都按預期工作-對Vertex對象所做的任何修改都將對原始值進行,因此這些更改在方法返回后仍然存在。 在第二種情況下,盡管v仍然是指針,但是Go編譯器足夠聰明,可以將v.Scale(5)轉換為(*v).Scale(5) ,其中v被取消引用,並將結果值傳遞給Scale

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM