Go Lang的切片append()
可能会分配一个新的支持数组,以便为新项目腾出空间。因此,在调用z = append(x,y)
之后,如果z
的最前面的元素被修改,x
基本上是未指定的 - 它可能或可能不具有与{{1}相同的后备数组} {和z
可以使用z
改变其后备数组,因此可能会修改z[0] = foo
的后备数组。
那么,为什么要让这个丑陋的表面?而不是将程序错误分配给除了第一个参数之外的任何内容的附加结果,为什么不让x
取代append
,因此不需要重新分配,也不会留下任何未定义的变量。< / p>
这并不能解决所有情况,因为*[]T
仍会使a = x; append(&x,y)
未定义,但部分改进似乎比没有好。
答案 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)
个元素。 在其中任何一种情况下,x
在x
的所有元素仍然存在的意义上基本保持不变。你现在显然必须要小心,因为你可能有两个对相同底层数据的引用,但重点是保持x
可能是有用的。
那就是说,我同意可能让append
占用一个指针可能更简单,也许我刚才描述的这个可能的用例并不常见,不足以保证可能令人困惑,更温和更冗长的语义