考慮以下代碼:
package main
import (
"fmt"
)
type Person struct {
Age int
M map[string]func()
}
func New() Person {
p := Person{1, make(map[string]func())}
p.M["1"] = p.Add
return p
}
func (p *Person) Add() {
fmt.Println("Age before mutating in Add", p.Age)
p.Age = 1 // here age should become 3
fmt.Println("Age after mutating in Add", p.Age)
}
func (p *Person) Run() {
fmt.Println("Age before mutating in Run", p.Age)
p.Age = 1 // here age should be 2
p.M["1"]()
fmt.Println("Age after mutating in Run", p.Age)
}
func main() {
p := New()
fmt.Println("age before", p.Age)
p.Run()
fmt.Println("age after", p.Age)
}
這產生輸出
age before 1
Age before mutating in Run 1
Age before mutating in Add 1
Age after mutating in Add 2
Age after mutating in Run 2
age after 2
這M是一個結構體的映射成員,它針對字串存盤相同結構體的方法。
在 main 中,我們實體化了一個非指標結構值。
然后我們Run在該結構上呼叫一個方法,該方法被定義為具有指標接收器。這應該與方法共享一個指向結構的指標,這應該允許方法改變原始結構。
在內部,Run我們Add通過地圖呼叫存盤在地圖中的函式。但這不會改變結構,實際上它似乎對物件的狀態進行操作,就像新創建時一樣。
Add時間Run結束時,其中的任何更改都將丟失,盡管Add也使用指標接收器宣告。
我懷疑這是因為原始物件在呼叫時以某種方式復制到地圖中p.M["1"] = p.Add?
為什么使用指標接收器呼叫方法不會改變物件?
游樂場鏈接https://play.golang.org/p/CRer_rT8_sj
uj5u.com熱心網友回復:
New回傳 aPerson而不是 a *Person。
當你寫
p := New()
它從New構造一個 Personpnew并將其 Add 方法添加到pnew.M. 然后它回傳pnew。
然后將 thispnew分配給pwhich 是一個不同的變數。所以p.M包含 nowpnew的 Add 方法。當您p.M["1"]()在 Run 中執行時,pnewAge 會增加(與p's age.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/362236.html
上一篇:使用佇列時跳過SQS訊息
下一篇:發送HTTP/2請求
