'Mutating a slice field of a struct even though all methods are defined with value receivers
6.2 Methods with a Pointer Receiver
If all the methods of a named type T have a receiver type of T itself (not *T ), it is safe to copy instances of that type; calling any of its methods necessarily makes a copy. For example, time.Duration values are liberally copied, including as arguments to functions. But if any method has a pointer receiver, you should avoid copying instances of T because doing so may violate internal invariants. For example, copying an instance of bytes.Buffer would cause the original and the copy to alias ( §2.3.2 ) the same underlying array of bytes. Subsequent method calls would have unpredictable effects.
(The Go Programming Language Alan A. A. Donovan · Brian W. Kernighan)
I understand the general meaning of the quote, but I am wondering whether it's correct to say that is safe to copy instances of that type.
If a struct has a slice/map field then all copies receive their own copies of the pointers to the backing array/hashmap so it is still possible to mutate those data structures.
Even though all the methods might be defined using value receivers, we can break the internal state of the struct.
I understand why that happens, but doesn't that possibility contradict what is written in that paragraph above?
Copying values might have unwanted consequences regardless of the method receivers and also depends on the field types.
What am I missing here?
package main
import "fmt"
type T struct {
s []string
}
func main() {
original := T{s: []string{"original"}}
copycat := original
copycat.s[0] = "copycat"
fmt.Println(original.s[0] == "copycat") // true
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
