对slice上的append()行为感到困惑 [英] Confused about append() behavior on slices

查看:126
本文介绍了对slice上的append()行为感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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)
}

结果:

[10000 1 0 0 0 0 0 0 0 0]

[10000 1 0 0 0 0 0 0 0 0]

[10000 1 0 0 0 0 0 0 0 0]

[10000 1 0 0 0 0 0 0 0 0]

在我的理解中, slice 是一个指针, slice1 slice 指向同一数组,并且第一个输出也证明了这一点.但是为什么在附加操作更改了 slice1 slice 的值保持不变?

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?

推荐答案

append() 没有更改 slice1 ;它不能,因为Go中的所有内容都是按值传递的,因此它仅接收到它的一个副本.由于最初创建的 slice 的容量等于其长度( make([] int,10,10)),所以任何元素多于0的附加操作都需要分配一个更大的新阵列.这就是您的 append()调用所做的.然后它复制旧数组的内容,并返回一个指向新数组的切片值(切片头).然后您将返回值 assign 分配给 slice1 ,并且该 assignment 是更改 slice1 的内容.

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.

slice1 的任何赋值都不会更改 slice 的值,它们是2个不同的变量,2个不同的切片头.因此,附加的元素在 slice 中将不可见.由于 append()必须创建一个新数组,因此对 slice1 slice elements 进行了更改也不会再相互反映.

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.

要查看切片头中包含的内容,请参见 golang切片是否通过按价值?

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.

这篇关于对slice上的append()行为感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆