I have come across a bit of unexplained behavior of go's big.Int when pointing an instance of one big.Int to another.
I am knowledgeable that in order to set a value of a bit.Int's instance to another, one must use the Int.SetXXX setters, because they actually cause the underlying abs slice in big.Int to be copied to a newly allocated array. However, putting that aside for a moment, I'd like to know why the following behavior occurs.
Consider the following:
Wrong example (underlying value mutates):
func main() {
v1p := big.NewInt(1)
v2p := big.NewInt(2)
v1 := *v1p
v2 := *v2p
v2 = v1
v1.SetInt64(3)
fmt.Println(v1.Int64(), v2.Int64())
}
(run here: https://play.golang.org/p/WxAbmGdKG9b)
Correct example (value does not mutate):
func main() {
v1p := big.NewInt(1)
v2p := big.NewInt(2)
v1 := *v1p
v2 := *v2p
v2.Set(v1p)
v1.SetInt64(3)
fmt.Println(v1.Int64(), v2.Int64())
}
(run here: https://play.golang.org/p/16qsGhwHIWf)
If I understand correctly, the following should essentially demonstrate what happens in the wrong example:
func main() {
var a, b *int // analogous to the 2 big.Int pointers returned
c, d := 3, 3
a = &c // we set the pointers to point to something we can then dereference
b = &d
e := *a // e and f should now point to the values pointed to by the pointers
f := *b
// the rest is self-explanatory
e = f
c = 5
d = 4
fmt.Println(a, b, c, d, e, f)
}
(run here: https://play.golang.org/p/cx76bnmJhG7)
My only assumption is that somehow when copying the struct content onto v2 in the Wrong example, what happens is that abs slice does not get deep-copied but that the storage that it references is actually the same storage that the slice in v1 points to.
Is this really what happens? Is this the expected behavior according to the language spec too?