duanmao2774 2019-07-18 18:17
浏览 111
已采纳

Go slice容量在追加时如何变化? [重复]

This question already has an answer here:

Running the example The Go Tour on server (currently on version 1.12.7), I find the capacity of slice doubling to the next power of 2, if the new slice length is larger than current backing array's length.

If I run the same program on my machine (version 1.10.3 on windows), the slice capacity changes to next multiple of two.

Why are they different? Is it because of Go version or run-time implementations? Is the capacity change deterministic?

The output on remote server is this

len=0 cap=0 []
len=1 cap=2 [0]
len=2 cap=2 [0 1]
len=5 cap=8 [0 1 2 3 4]

The output on local machine is this

len=0 cap=0 []
len=1 cap=1 [0]
len=2 cap=2 [0 1]
len=5 cap=6 [0 1 2 3 4]

This is the code for reference

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
", len(s), cap(s), s)
}
</div>
  • 写回答

2条回答 默认 最新

  • dsmnedc798226 2019-07-18 19:06
    关注

    TL;DR: It depends on the size of the elements stored in the array

    The implementation can be seen here:

    https://github.com/golang/go/blob/master/src/runtime/slice.go

    But as you can see looking into the history it can't be relied to stay the same over time.

    That might also explain the difference you may note on different versions of Go.

    Making some tests show how a 0-size struct will increment capacity by just 1 element, and int or string will duplicate on each growth, and a 3-byte struct "roughly" doubles on each growth.

    You can execute code like this using different types to see these different cases in action:

    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))
        }
    }
    

    Playground showing the cases described above:

    https://play.golang.org/p/OKtCFskbp2t

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥50 safari浏览器fetch提交数据后数据丢失问题
  • ¥15 matlab不知道怎么改,求解答!!
  • ¥15 永磁直线电机的电流环pi调不出来
  • ¥15 用stata实现聚类的代码
  • ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
  • ¥20 docker里部署springboot项目,访问不到扬声器
  • ¥15 netty整合springboot之后自动重连失效
  • ¥15 悬赏!微信开发者工具报错,求帮改
  • ¥20 wireshark抓不到vlan
  • ¥20 关于#stm32#的问题:需要指导自动酸碱滴定仪的原理图程序代码及仿真