Confused about append() behavior on slices

大兔子大兔子 提交于 2021-02-05 12:15:57

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!