Understanding Pointer Receivers and Copying Instances
In Go, a method can be defined with either a value receiver or a pointer receiver. When all methods of a type T have a receiver type of T itself, it is safe to copy instances of that type, as calling any of its methods necessarily makes a copy.
However, the situation changes when a type has methods with a pointer receiver. In this case, copying instances of that type should be avoided, as it may violate internal invariants.
The Problem with Copying Pointers
Let's consider an example to illustrate the issue. Suppose we have a type Wrapper with two fields: a value v and a pointer p. We intend to store the same number in both v and the pointed value of p. To ensure this, we provide a Set method with a pointer receiver:
type Wrapper struct {
v int
p *int
}
func (w *Wrapper) Set(v int) {
w.v = v
*w.p = v
}
If we have an instance of Wrapper and call the Set method, it will modify the pointed value of p. However, if we make a copy of the instance, the copy will share the same pointer value p as the original instance. This means that any subsequent method calls on either instance will affect both copies.
Example:
a := Wrapper{v: 0, p: new(int)}
b := a
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
a.Set(1)
fmt.Printf("a.v=%d, a.p=%d; b.v=%d, b.p=%d\n", a.v, *a.p, b.v, *b.p)
Output:
a.v=0, a.p=0; b.v=0, b.p=0 a.v=1, a.p=1; b.v=0, b.p=1
In this example, the value of b becomes invalid after a.Set(1) is called, as b.v does not equal *b.p. This is because the pointer p in both a and b points to the same underlying value.
To avoid such issues, it is recommended to work with pointer values when using methods with pointer receivers. Alternatively, if the type can have value receivers only, it is safe to copy instances of that type regardless of method calls.
Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.
Copyright© 2022 湘ICP备2022001581号-3