Go 中透過指標接收器方法修改簡單型別值
在Go 中,我們可以基於基本型別建立自訂型別並擴充其功能透過指標接收器方法。然而,當嘗試透過指標接收器方法修改簡單類型的值時,會出現一個常見問題。
考慮以下範例:
package main import ( "fmt" "strconv" ) type FooInt int func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) tmp := FooInt(num) fi = &tmp // Attempt to modify the pointer } func main() { var fi *FooInt fi.FromString("5") fmt.Printf("%v\n", fi) // Prints <nil>, not the expected 5 }
為什麼指標 fi main() 中宣告的值不會改變為 tmp 的位址嗎?
說明
Go 中呼叫函數或方法時,所有參數,包括接收者,作為副本傳遞。這意味著您無法在函數/方法中修改原始指標值。
在上面的範例中,FromString 方法中的 fi 是 main() 中宣告的指標的副本。當您將 fi 指派給 tmp 的位址時,您只是變更了副本的值。原始指針保持不變。
解
此問題常見的解決方案有以下三種:
1.回指標:
func (fi *FooInt) FromString(i string) *FooInt { num, _ := strconv.Atoi(i) tmp := FooInt(num) return &tmp } func main() { var fi *FooInt fi = fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
2.傳遞指標參數:
func (fi *FooInt) FromString(i string, p **FooInt) { num, _ := strconv.Atoi(i) tmp := FooInt(num) *p = &tmp } func main() { var fi *FooInt fi = new(FooInt) // Ensure non-nil receiver fi.FromString("5", &fi) fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
3.確保接收者非零:
func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) *fi = FooInt(num) } func main() { var fi *FooInt fi = new(FooInt) // Ensure non-nil receiver fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }3.確保接收者非零:
以上是為什麼 Go 中無法透過指標接收器方法修改簡單型別值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!