为什么Go slice` append()`没有引用?

时间:2014-01-10 02:40:48

标签: go

Go Lang的切片append()可能会分配一个新的支持数组,以便为​​新项目腾出空间。因此,在调用z = append(x,y)之后,如果z的最前面的元素被修改,x基本上是未指定的 - 它可能或可能不具有与{{1}相同的后备数组} {和z可以使用z改变其后备数组,因此可能会修改z[0] = foo的后备数组。

那么,为什么要让这个丑陋的表面?而不是将程序错误分配给除了第一个参数之外的任何内容的附加结果,为什么不让x取代append,因此不需要重新分配,也不会留下任何未定义的变量。< / p>

这并不能解决所有情况,因为*[]T仍会使a = x; append(&x,y)未定义,但部分改进似乎比没有好。

1 个答案:

答案 0 :(得分:3)

在您的第一个示例(z = append(x, y))中,x未定义,这并不完全正确。相反,x仍指向x的原始内容,而z指向这些内容,然后指向某些内容。如你所述,有两种可能性:

  • cap(x) > len(x),在这种情况下append只返回x[:len(x)+1](即,扩展返回切片的长度以包含一个额外元素)
  • cap(x) == len(x),在这种情况下,append通过复制x的内容创建另一个数组,然后将y添加为len(x)个元素。

在其中任何一种情况下,xx的所有元素仍然存在的意义上基本保持不变。你现在显然必须要小心,因为你可能有两个对相同底层数据的引用,但重点是保持x可能是有用的。

那就是说,我同意可能让append占用一个指针可能更简单,也许我刚才描述的这个可能的用例并不常见,不足以保证可能令人困惑,更温和更冗长的语义