对切​​片

时间:2017-09-07 07:37:01

标签: go append slice

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]

根据我的理解,slice是一个指针,slice1slice指向同一个数组,第一个输出也证明了这一点。但是为什么slice的值在追加操作改变slice1之后保持不变?

2 个答案:

答案 0 :(得分:7)

append()没有改变slice1;它不能通过值传递Go中的所有内容,因此它只接收它的副本。由于最初创建的slice容量等于其长度(make([]int, 10, 10)),因此任何超过0个元素的追加操作都需要分配一个更大的新数组。这是您的append()电话所做的事情。它复制旧数组的内容,并返回指向新数组的切片值(切片标头)。并且的返回值分配给slice1,此assignment会更改slice1

slice1的任何分配都不会更改slice的值,它们是2个不同的变量,2个不同的切片标头。因此,slice中不会显示附加的元素。由于append()必须创建新数组,因此对slice1slice元素所做的更改也不会再相互反映。< / p>

要查看切片标头内的内容,请参阅Are golang slices pass by value?

要了解有关切片的更多信息,请阅读博文Go Slices: usage and internals

答案 1 :(得分:2)

因为append可以决定返回基础数组的全新副本