go - 追加时数组大小不加倍

标签 go slice

为了

package main

import "fmt"

func main() {


    b := make([]int, 1, 5)  
    printSlice("b", b[:cap(b)])
    
    b2 := append(b, 1)
    b3 := append(b2, 1)
    b4 := append(b3, 1)
    b5 := append(b4, 1)
    
    printSlice("bbbb", b5[:cap(b5)])
    
    b6 := append(b5, 1)
    
    printSlice("bbbb", b6[:cap(b6)])
    
    
}

func printSlice(s string, x []int) {
    fmt.Printf("%s len=%d cap=%d %v\n",
        s, len(x), cap(x), x)
}
结果是
b len=5 cap=5 [0 0 0 0 0]
bbbb len=5 cap=5 [0 1 1 1 1]
bbbb len=10 cap=10 [0 1 1 1 1 1 0 0 0 0]
看起来最后一个追加是基础数组大小的两倍,有没有办法说成它是大小6?

最佳答案

如果使用内置的 append() ,则无法控制结果容量。它没有记录容量增长策略,因此没有什么可期待的(除了要添加的元素将适合其中)。考虑到 future 的增长(减少 future 的分配),它通常会分配超过所需的资源。 Spec: Appending to and copying slices列出您保留append()的所有“保证人”,以及由此产生的 slice 的容量:

If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.


如果要控制生成的片的容量,则必须自己分配它,在旧片上复制并追加到新片上,例如:
b6 := make([]int, len(b5), len(b5)+1)
copy(b6, b5)
b6 = append(b6, 1)
然后输出将是(在Go Playground上尝试):
b len=5 cap=5 [0 0 0 0 0]
bbbb len=5 cap=5 [0 1 1 1 1]
bbbb len=6 cap=6 [0 1 1 1 1 1]
如您所见,有一个“很多”需要完成:要创建新的 slice (具有后备数组),将旧的复制过来,然后执行追加操作(可以通过创建新的 slice 来优化,例如make([]int, len(b5)+1),然后最后的附件只是b6[len(b6-1] = 1)。附加单个元素时,一直都这样做很浪费,这就是append()分配更多资源的原因,因此不必一直执行。
查看相关问题:
Go slices - capacity/length?
Golang slice append vs assign performance
Insert a value in a slice at a given index
Concatenate two slices in Go

关于go - 追加时数组大小不加倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64010871/

相关文章:

image - 如何在golang中将白色背景更改为透明?

qt - 使用 qt 样式表在拉伸(stretch)边框图像时保留 Angular

python - 带有 MultiIndex Pandas 面板的切片函数

go - 如何限制Google Storage的已签名上传网址的内容类型?

python - 对实值张量进行分桶

arrays - 如何将 byte slice 段 (&[u8]) 的缓冲区转换为整数?

python - NumPy 。如何将二维数组按网格分割为多个数组?

go - 消费者失败时关闭 amqp.Channel 没有响应

mongodb - Docker 和 mongo-go-driver "server selection error"

go - 为具有多个包的项目做出贡献