考虑下面的go代码:
fruits := [4]string{"apple", "orange", "mango"} tasty_fruits := fruits[1:3] fmt.Println(len(tasty_fruits)) fmt.Println(cap(tasty_fruits)) fmt.Println(tasty_fruits)
:
2 3 [orange mango]
我不明白的是,为什么taste_fruits的容量为3,直觉上我希望为2,因为这是切片的长度?
而且,如果tasty_fruits的容量为3,那么为什么:
tasty_fruits[2] = "nectarine"
造成:
panic: runtime error: index out of range
这行:
fruits := [4]string{"apple", "orange", "mango"}
创建一个 数组 ,而不是一个切片。即使您仅提供了3个元素,它也有4个元素。输出fmt.Printf("%q", fruits):
fmt.Printf("%q", fruits)
["apple" "orange" "mango" ""]
切片:
tasty_fruits := fruits[1:3]
结果是:
["orange" "mango"]
长度:明显2.容量?
的 容量 是…的片的长度和超过所述切片中的[基本]阵列的长度的总和。
由于"mango"底层数组中仅包含一个元素,因此容量为2 + 1 = 3。
"mango"
2 + 1 = 3
索引切片(tasty_fruits):规范:索引表达式:
tasty_fruits
对于a切片类型S:a[x] 如果x在运行时超出范围,则会发生运行时恐慌
对于a切片类型S:a[x]
a
S
a[x]
x
x如果为0 <= x < len(a),则在范围内,否则为超出范围。由于len(tasty_fruits)is 2,索引2超出范围,因此发生运行时恐慌。
0 <= x < len(a)
len(tasty_fruits)
2
即使容量允许,也无法索引超出片段长度的片段。如果您对切片进行切片,则只能达到超出长度的元素,例如:
tasty_fruits2 := tasty_fruits[:3] tasty_fruits2[2] = "nectarine" // This is ok, len(tasty_fruits2) = 3 fmt.Printf("%q", tasty_fruits2)
输出:
["orange" "mango" "nectarine"]