原切片非空情况下:
// src/runtime/slice.go
func growslice(et *_type, old slice, cap int) slice {
// ...省略部分
newcap := old.cap
doublecap := newcap + newcap
if cap > doublecap {
newcap = cap
} else {
if old.len < 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
}
}
}
// ...省略部分
}
-
当需要的容量超过原切片容量的两倍时,会使用需要的容量作为新容量。
-
当原切片长度小于1024时,新切片的容量会直接翻倍。而当原切片的容量大于等于1024时,会反复地增加25%,直到新容量超过所需要的容量。
原切片为空的情况下:
// int8
a := []int8{}
for i := 0; i < 16; i++ {
a = append(a, 1, 2, 3, 4, 5, 6)
fmt.Print(cap(a), " ")
}
// 8 16 32 32 32 64 64 64 64 64 128 128 128 128 128 128
// int16
fmt.Println()
b := []int16{}
for i := 0; i < 16; i++ {
b = append(b, 1, 2, 3, 4, 5)
fmt.Print(cap(b), " ")
}
// 8 16 32 32 32 64 64 64 64 64 128 128 128 128 128 128
// bool
fmt.Println()
c := []bool{}
for i := 0; i < 16; i++ {
c = append(c, true, false, true, false, false)
fmt.Print(cap(c), " ")
}
// 8 16 32 32 32 64 64 64 64 64 128 128 128 128 128 128
// float32
fmt.Println()
d := []float32{}
for i := 0; i < 16; i++ {
d = append(d, 1.1, 2.2, 3.3, 4.4, 5.5)
fmt.Print(cap(d), " ")
}
// 8 16 16 32 32 32 64 64 64 64 64 64 128 128 128 128
// float64
fmt.Println()
e := []float64{}
for i := 0; i < 16; i++ {
e = append(e, 1.1, 2.2, 3.3, 4.4, 5.5)
fmt.Print(cap(e), " ")
}
// 6 12 24 24 48 48 48 48 48 96 96 96 96 96 96 96
// string
fmt.Println()
f := []string{}
for i := 0; i < 16; i++ {
f = append(f, "1.1", "2.2", "3.3", "4.4", "5.5")
fmt.Print(cap(f), " ")
}
// 5 10 20 20 40 40 40 40 80 80 80 80 80 80 80 80
// []int
fmt.Println()
g := [][]int{}
g1 := []int{1, 2, 3, 4, 5}
for i := 0; i < 16; i++ {
g = append(g, g1, g1, g1, g1, g1)
fmt.Print(cap(g), " ")
}
// 5 10 20 20 42 42 42 42 85 85 85 85 85 85 85 85