TL; DR:指針接收器需要它的價值之前被取消引用可以設置。這適用於結構和非結構類型。在結構類型的情況下,解引用是由選擇器表達式自動完成的。
經過深入挖掘,我認爲這種行爲是由於指針接收器不是調用該方法的同一指針引起的。
運行此代碼片段顯示main()
函數中的u
指針與defaultIP()
方法中的指針不同。實質上,我最終只能修改方法中的u
指針。可執行示例可以找到here。
func main() {
var u *userIP
u.defaultIP()
fmt.Printf("main(): address of pointer is %v\n", &u)
fmt.Printf("main(): user IP address is %v\n", u)
}
type userIP net.IP
func (u *userIP) defaultIP() {
defaultIP := userIP("127.0.0.1")
u = &defaultIP
fmt.Printf("defaultIP(): address of pointer is %v\n", &u)
fmt.Printf("defaultIP(): user IP address is %s\n", *u)
}
正確的方法做,這是爲指向湯姆的回答,即取消引用的defaultIP()
方法u
。
我之前感到困惑的是,爲什麼如果我將IP作爲字段包裝在結構中時,此示例會起作用?運行代碼片段顯示兩個u
指針確實不同,但ip
字段被修改。可執行的例子可以發現here。
func main() {
u := &userInfo{}
u.defaultIP()
fmt.Printf("main(): address of pointer is %v\n", &u)
fmt.Printf("main(): user IP address is %s\n", u.ip)
}
type userInfo struct{
ip net.IP
}
func (u *userInfo) defaultIP() {
u.ip = net.ParseIP("127.0.0.1")
fmt.Printf("defaultIP(): address of pointer is %v\n", &u)
fmt.Printf("defaultIP(): user IP address is %s\n", u.ip)
}
原來,這是由selector expression(x.y
)引起的。引用該文檔,
選擇器自動將指針指向結構體。如果x是指向結構體的指針,則x.y是(x).y的簡寫形式;如果字段y也是指向結構體的指針,則x.y.z是((* x).y).z的簡寫形式,依此類推。如果x包含類型* A的匿名字段,其中A也是結構類型,則x.f是(* x.A).f的快捷方式。
所以在我的情況下,u.ip
表達修改ip
領域,基本上轉化爲(*u).ip
之前取消引用u
。
解除引用*(我試過編輯它,但它不允許我,因爲更改少於6個字符) – Kul
讀者需要點擊鏈接才能理解此答案。 (除非你已經知道解除引用的意思,但即便如此,你如何做到這一點在golang中點擊鏈接找出:D – Jacob