首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >追加时不会使数组大小加倍

追加时不会使数组大小加倍
EN

Stack Overflow用户
提问于 2020-09-22 21:33:21
回答 2查看 145关注 0票数 0

代码语言:javascript
复制
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)
}

结果是

代码语言:javascript
复制
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?

EN

回答 2

Stack Overflow用户

发布于 2020-09-22 21:39:48

如果你使用的是内置的append(),你不能控制结果的容量。它没有记录容量增长策略,所以没有什么可期待的(除了附加的元素将适合它)。考虑到未来的增长(以减少未来的分配),它通常会分配比需要更多的资源。Spec: Appending to and copying slices列出了您对append()和生成的切片的容量要求的所有“保证”:

如果s的容量不足以容纳附加值,append将分配一个新的足够大的底层数组,该数组既能容纳现有切片元素,又能容纳附加值。否则,append将重用底层数组。

如果你想控制产生的切片的容量,你必须自己分配它,复制旧的切片并附加到新的切片上,例如:

代码语言:javascript
复制
b6 := make([]int, len(b5), len(b5)+1)
copy(b6, b5)
b6 = append(b6, 1)

然后输出将是(在Go Playground上试用):

代码语言:javascript
复制
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]

正如您所看到的,需要做的事情有很多:创建新片(使用后备数组)、复制旧片,然后是追加操作(这可以通过创建新片来优化,如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

票数 5
EN

Stack Overflow用户

发布于 2020-09-22 21:39:41

有没有办法说把它做成6号?

不是的。Append做它做的事情。但是,没有什么能阻止您提供具有所需上限的切片。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64010871

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档