I am seeing weird behavior in the following code:
type A struct {
D []int8
}
func main() {
a := A{D: make([]int8, 0)}
a.D = append(a.D, 0)
b := a
c := a
b.D = append(b.D, 1)
c.D = append(c.D, 2)
fmt.Println(a.D, b.D, c.D)
}
I'm expecting output to be
[0] [0 1] [0 2]
However I got
[0] [0 2] [0 2]
Anyone know why...?
p.s. If I comment out line "a.D = append(a.D, 0)", or change the type of D from "[ ]int8" to "[ ]int", I got what I expected. Weird...
First off, changing the type doesn't fix it: https://play.golang.org/p/fHX3JAtfNz
What is happening here has to do with the mechanics of append and reference types.
Basically, all three structs are pointing at the same underlying array, but each slice has its own unique length argument.
So when you append 1 to b, it is [0 1] with a length of 2. c is still [0] with a length of 1. You then append 2 to c, making it [0 2] with a length of 2. Inadvertently, you are also changing the second value of the array in b. If you could change the length of the a without append, it would also be [0 2].
Make sense? Pointers and slices are weird. Full story is here: https://blog.golang.org/slices