下面的程序有意外的输出。
func main(){
s:=[]int{5}
s=append(s,7)
s=append(s,9)
x:=append(s,11)
y:=append(s,12)
fmt.Println(s,x,y)
}
输出:[5 7 9] [5 7 9 12] [5 7 9 12]
为什么x
的最后一个元素是12
?
最佳答案
slice 只是数组部分的一个窗口,它没有特定的存储空间。
这意味着如果数组的同一部分有两个 slice ,则两个 slice 必须“包含”相同的值。
这正是这里发生的事情:
- 当您执行第一个
append
时,您会在大小为2
的基础数组上获得一个大小为2
的新 slice 。 - 当您执行下一个
append
时,您会得到一个大小为3
的新 slice ,但底层数组的大小为4
(append
通常分配比立即需要的空间更多的空间,因此它不需要在每次追加时分配)。 - 这意味着下一个
append
不需要新数组。所以x
和y
都将使用与前面 slices
相同的底层数组。你在这个数组的同一个槽中编写11
然后12
,即使你得到两个不同的 slice (记住,它们只是窗口)。
您可以通过在每次追加后打印 slice 的容量来检查:
fmt.Println(cap(s))
如果你想在 x
和 y
中有不同的值,你应该做一个 copy ,例如像这样:
s := []int{5}
s = append(s, 7)
s = append(s, 9)
x := make([]int,len(s))
copy(x,s)
x = append(x, 11)
y := append(s, 12)
fmt.Println(s, x, y)
这里的另一种解决方案可能是强制 s
slice 后面的数组的容量不大于所需的容量(从而确保以下两个 append
< em>必须使用新数组):
s := []int{5}
s = append(s, 7)
s = append(s, 9)
s = s[0:len(s):len(s)]
x := append(s, 11)
y := append(s, 12)
fmt.Println(s, x, y)
关于arrays - 谁能解释这种附加到 golang slice 的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27568213/