问题
func main() {
slice := make([]int, 10, 10)
slice[0] = 0
slice[1] = 1
slice1 := slice
slice1[0] = 10000
fmt.Println(slice)
slice1 = append(slice1, 100)
slice1[0] = 20000
fmt.Println(slice)
}
result:
[10000 1 0 0 0 0 0 0 0 0]
[10000 1 0 0 0 0 0 0 0 0]
In my understanding, slice
is a pointer, slice1
and slice
point to the same array, and the first output also proves this. But why did slice
's value remain unchanged after the append operation changed slice1
?
回答1:
The append() didn't change slice1
; it can't as everything in Go is passed by value, so it only receives a copy of it. Since initially you created the slice
with capacity equal to its length (make([]int, 10, 10)
), any append operation with more than 0 elements requires allocation of a new, bigger array. This is what your append()
call does. And it copies over the contents of the old array, and returns a slice value (slice header) pointing to the new array. And you assign the return value to slice1
, and this assignment is what changes slice1
.
Any assignment to slice1
does not change the value of slice
, they are 2 distinct variables, 2 distinct slice headers. So the appended elements will not be visible in slice
. And since the append()
had to create a new array, changes made to the elements of slice1
and slice
will also not be reflected in one another anymore.
To see what's inside a slice header, see Are golang slices pass by value?
To learn more about slices, read blog post Go Slices: usage and internals.
回答2:
Because an append can decide to return an entirely new copy of the underlying array.
来源:https://stackoverflow.com/questions/46090572/confused-about-append-behavior-on-slices