This question already has an answer here:
How the slice is enlarged by append? Is the capacity always doubled?
(1个答案)
1年前关闭。
在服务器上运行示例The Go Tour(当前在1.12.7版上),如果新的 slice 长度大于当前支持数组的长度,我发现 slice 的容量将增加一倍,达到下一个2的幂。
如果我在计算机上运行相同的程序(Windows上为1.10.3版),则 slice 容量将更改为2的下一个倍数。
他们为什么不同?是因为Go版本还是运行时实现?容量变化是确定的吗?
远程服务器上的输出是这个
本地计算机上的输出是这个
这是引用代码
显示上述情况的游乐场:
https://play.golang.org/p/OKtCFskbp2t
(1个答案)
1年前关闭。
在服务器上运行示例The Go Tour(当前在1.12.7版上),如果新的 slice 长度大于当前支持数组的长度,我发现 slice 的容量将增加一倍,达到下一个2的幂。
如果我在计算机上运行相同的程序(Windows上为1.10.3版),则 slice 容量将更改为2的下一个倍数。
他们为什么不同?是因为Go版本还是运行时实现?容量变化是确定的吗?
远程服务器上的输出是这个
len=0 cap=0 []
len=1 cap=2 [0]
len=2 cap=2 [0 1]
len=5 cap=8 [0 1 2 3 4]
本地计算机上的输出是这个
len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]
这是引用代码
package main
import "fmt"
func main() {
var s []int
printSlice(s)
// append works on nil slices.
s = append(s, 0)
printSlice(s)
// The slice grows as needed.
s = append(s, 1)
printSlice(s)
// We can add more than one element at a time.
s = append(s, 2, 3, 4)
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
最佳答案
TL; DR:这取决于存储在数组中的元素的大小
可以在这里看到实现:
https://github.com/golang/go/blob/master/src/runtime/slice.go
但是,正如您所看到的,回顾历史不能一直保持不变。
这也可以解释您在Go的不同版本上可能会注意到的差异。
进行一些测试表明,大小为0的结构将如何仅将容量增加1个元素,并且每次增长时int或string都将重复,而每次增长时3字节结构将“大约”翻倍。
您可以使用不同的类型执行类似的代码,以查看这些不同的情况:
arr := []struct{}{}
oldCap := 0
for i := 0; i < 100; i++ {
arr = append(arr, struct{}{})
if cap(arr) != oldCap {
oldCap = cap(arr)
fmt.Println("arr", cap(arr))
}
}
显示上述情况的游乐场:
https://play.golang.org/p/OKtCFskbp2t
关于go - Go slice容量在追加时如何变化? [复制],我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57100525/