对golang切片帽的困惑

我有一个关于切片帽的问题,代码:

var slice []int
list := []int{1,2,3,4,5}
for _,item := range list {
    slice = append(slice, item)
}
fmt.Println(len(slice),cap(slice))

如果 item == 1: len(slice)=1,cap(slice)=1

如果 item == 2: len(slice)=2,cap(slice)= 1*2

if item ==3: len(slice) = 3,cap(slice) = 2*2

if item == 4:len(slice) = 4,cap(slice) = 4

if item == 5:len(slice) = 5,cap(slice) = 4*2

所以输出:

len(slice) = 5,cap(slice) = 8

那没问题,但是当我更改代码时:

var slice []int
slice = append(slice,1,2,3,4,5)
fmt.Println(len(slice),cap(slice))

输出:

len(slice) = 5,cap(slice) = 6

为什么 cap(slice) = 6 ?

回答

func growslice(et *_type, old slice, cap int)在src/runtime/slice.go中追加时可以看到容量计算的算法-第162行

    newcap := old.cap
    doublecap := newcap + newcap
    if cap > doublecap {
        newcap = cap
    } else {
        if old.cap < 1024 {
            newcap = doublecap
        } else {
            // Check 0 < newcap to detect overflow
            // and prevent an infinite loop.
            for 0 < newcap && newcap < cap {
                newcap += newcap / 4
            }
            // Set newcap to the requested cap when
            // the newcap calculation overflowed.
            if newcap <= 0 {
                newcap = cap
            }
        }
    }
  • 先将旧切片容量乘以2,如果乘以2后容量仍小于新切片容量,则取新切片容量(追加多个elems)
  • 如果新切片小于旧切片容量的两倍,则将旧切片容量乘以 2
  • 如果旧分片容量大于等于1024,则新分片容量乘以旧分片容量乘以1.25

参考 -

  • 源代码/运行时/slice.go
  • 容量增长算法-golang-slice-append

以上是对golang切片帽的困惑的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>