When reading up on Go slices, I came across this behaviour in the context of the append
method
If the backing array of s is too small to fit all the given values a bigger array will be allocated. The returned slice will point to the newly allocated array.
Source - Golang Tour
To understand this I wrote the following piece of code:
func makeSlices() {
var a []int;
a = append(a, 0)
b := append(a, 1)
printSlice("b", b)
c := append(a, 2)
printSlice("b", b)
printSlice("c", c)
}
func printSlice(name string, s []int) {
fmt.Printf("var=%v len=%d cap=%d first_address=%v %v
", name, len(s), cap(s), &s[0], s)
}
Output:
var=b len=2 cap=2 first_address=0x414020 [0 1]
var=b len=2 cap=2 first_address=0x414020 [0 2]
var=c len=2 cap=2 first_address=0x414020 [0 2]
I would expect b
and c
to point to the same underlying array as they both are slices of the same length
But if I were to vary the same code for another length of slice:
func makeSlices() {
var a []int;
a = append(a, 0, 9)
d := append(a, 1, 2)
printSlice("d", d)
e := append(a, 3, 4)
printSlice("d", d)
printSlice("e", e)
}
Output:
var=d len=5 cap=8 first_address=0x450020 [0 0 9 1 2]
var=d len=5 cap=8 first_address=0x450020 [0 0 9 1 2]
var=e len=5 cap=8 first_address=0x450040 [0 0 9 3 4]
In this scenario, d
and e
should point to the same backing array as they are again slices of the same length but they do not.
Why this anomaly in behaviour? When exactly does Go decide to allocate a new backing array to a slice?