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 }
以上是为什么 Go 中无法通过指针接收器方法修改简单类型值?的详细内容。更多信息请关注PHP中文网其他相关文章!