一尘不染

去切片长度为容量-1,为什么?

go

考虑下面的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

阅读 223

收藏
2020-07-02

共1个答案

一尘不染

这行:

fruits := [4]string{"apple", "orange", "mango"}

创建一个 数组 ,而不是一个切片。即使您仅提供了3个元素,它也有4个元素。输出fmt.Printf("%q", fruits)

["apple" "orange" "mango" ""]

切片:

tasty_fruits := fruits[1:3]

结果是:

["orange" "mango"]

长度:明显2.容量?

容量 是…的片的长度和超过所述切片中的[基本]阵列的长度的总和。

由于"mango"底层数组中仅包含一个元素,因此容量为2 + 1 = 3

索引切片(tasty_fruits):规范:索引表达式

对于a切片类型Sa[x]

  • 如果x在运行时超出范围,则会发生运行时恐慌

x如果为0 <= x < len(a),则在范围内,否则为超出范围。由于len(tasty_fruits)is
2,索引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"]
2020-07-02