In Go, pointer receivers in methods allow you to modify the original value of a struct. However, this doesn't apply to simple types. This question delves into why such modifications don't work and presents solutions.
Consider this code:
package main import ( "fmt" "strconv" ) type FooInt int func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) tmp := FooInt(num) fi = &tmp } func main() { var fi *FooInt fi.FromString("5") fmt.Printf("%v\n", fi) // Prints <nil> }
Here, you'd expect the function FromString to set the value of fi to 5. But it prints
In Go, function/method arguments, including the receiver, are copies of the original values. As a result, modifications within the function only affect the copy.
Even for pointers, the receiver is a copy of the original pointer, not the actual pointer itself. Thus, modifications made to the receiver's value won't affect the original pointer.
To resolve this, there are several options:
Return the Modified Pointer:
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 }
Pass a Pointer to Modify:
func (fi *FooInt) FromString(i string, p **FooInt) { num, _ := strconv.Atoi(i) tmp := FooInt(num) *p = &tmp } func main() { var fi *FooInt fi.FromString("5", &fi) fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
Ensure Non-Nil Receiver:
func (fi *FooInt) FromString(i string) { num, _ := strconv.Atoi(i) *fi = FooInt(num) } func main() { fi := new(FooInt) // Initialize to non-nil fi.FromString("5") fmt.Printf("%v %v\n", fi, *fi) // Prints 0xc0000b4020 5 }
By adopting one of these solutions, you can effectively modify the value of simple types using pointer receivers.
The above is the detailed content of Why Can\'t I Modify a Simple Type\'s Value Using a Pointer Receiver in Go?. For more information, please follow other related articles on the PHP Chinese website!