I think the original answer is not exactly correct. append()
changed both the slices and the underlying array even though the underlying array is changed but still shared by both of the slices.
As specified by the Go Doc:
A slice does not store any data, it just describes a section of an underlying array. (Link)
Slices are just wrapper values around arrays, meaning that they contain information about how they slice an underlying array which they use to store a set of data. Therefore, by default, a slice, when passed to another method, is actually passed by value, instead of reference/pointer even though they will still be using the same underlying array. Normally, arrays are also passed by value too, so I assume a slice points at an underlying array instead of store it as a value. Regarding your question, when you run passed your slice to the following function:
func Test(slice []int) {
slice = append(slice, 100)
fmt.Println(slice)
}
you actually passed a copy of your slice along with a pointer to the same underlying array.That means, the changes you did to the slice
didn't affect the one in the main
function. It is the slice itself which stores the information regarding how much of an array it slices and exposes to the public. Therefore, when you ran append(slice, 1000)
, while expanding the underlying array, you also changed slicing information of slice
too, which was kept private in your Test()
function.
However, if you have changed your code as follows, it might have worked:
func main() {
for i := 0; i < 7; i++ {
a[i] = i
}
Test(a)
fmt.Println(a[:cap(a)])
}
The reason is that you expanded a
by saying a[:cap(a)]
over its changed underlying array, changed by Test()
function. As specified here:
You can extend a slice's length by re-slicing it, provided it has sufficient capacity. (Link)