我正在回顾 Go 之旅,我遇到了这些练习:
package main
import "fmt"
func main() {
s := []int{2, 3, 5, 7, 11, 13}
printSlice(s)
// Slice the slice to give it zero length.
s = s[:0]
printSlice(s)
// Extend its length.
s = s[:4]
printSlice(s)
// Drop its first two values.
s = s[2:]
printSlice(s)
}
func printSlice(s []int) {
fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)
}
打印:
len=6 cap=6 [2 3 5 7 11 13]
len=0 cap=6 []
len=4 cap=6 [2 3 5 7]
len=2 cap=4 [5 7]
我开始明白了,因为前一个切片 (s[:4]) 的长度为 4,所以新切片的容量将反映这个长度。
但后来我更进一步:
package main
import "fmt"
func main() {
a := make([]int, 5)
printSlice("a", a)
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)
}
func printSlice(s string, x []int) {
fmt.Printf("%s len=%d cap=%d %v\n",
s, len(x), cap(x), x)
}
打印:
a len=5 cap=5 [0 0 0 0 0]
b len=0 cap=5 []
c len=2 cap=5 [0 0]
d len=3 cap=3 [0 0 0]
现在我很困惑,因为 s[2:5] 的容量现在是 3,而不是前一个切片的长度。
有人可以解释一下这种行为吗?
切片是数组的视图。所以考虑到这一点:
// This creates a slice containing 0 elements, but still pointing to the underlying array, so capacity is still 6
s = s[:0]
printSlice(s)
// This create a slice containing 4 elements with the same underlying array
s = s[:4]
printSlice(s)
// This creates a slice starting from the 3rd element of the underlying array, with size 2 (containing 3rd and 4th elements)
s = s[2:]
printSlice(s)
在第二个示例中,
c[2:5]
创建了一个与c
具有相同底层数组的切片,其大小为5,但切片从第3个元素开始,因此c
的容量为3。