我有一个关于切片帽的问题,代码:
var slice []int
list := []int{1,2,3,4,5}
for _,item := range list {
slice = append(slice, item)
}
fmt.Println(len(slice),cap(slice))
Run Code Online (Sandbox Code Playgroud)
如果 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))
Run Code Online (Sandbox Code Playgroud)
输出:
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
}
}
}
Run Code Online (Sandbox Code Playgroud)
- 先将旧切片容量乘以2,如果乘以2后容量仍小于新切片容量,则取新切片容量(追加多个elems)
- 如果新切片小于旧切片容量的两倍,则将旧切片容量乘以 2
- 如果旧分片容量大于等于1024,则新分片容量乘以旧分片容量乘以1.25
参考 -