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

Tho*_*mas 1 arrays go slice

考虑下面的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)
Run Code Online (Sandbox Code Playgroud)

.OUPUTS:

2
3
[orange mango]
Run Code Online (Sandbox Code Playgroud)

我不明白为什么Tasty_fruits 3的容量,直觉上我会期望它是2,因为这是切片的长度?

如果tasty_fruits的容量为3,为什么:

tasty_fruits[2] = "nectarine"
Run Code Online (Sandbox Code Playgroud)

造成:

panic: runtime error: index out of range
Run Code Online (Sandbox Code Playgroud)

icz*_*cza 9

这一行:

fruits := [4]string{"apple", "orange", "mango"}
Run Code Online (Sandbox Code Playgroud)

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

["apple" "orange" "mango" ""]
Run Code Online (Sandbox Code Playgroud)

切片:

tasty_fruits := fruits[1:3]
Run Code Online (Sandbox Code Playgroud)

结果是:

["orange" "mango"]
Run Code Online (Sandbox Code Playgroud)

长度:显然2.容量?

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

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

为slice(tasty_fruits)编制索引:spec:索引表达式:

对于a切片类型S:a[x]

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

x是否在范围内0 <= x < len(a),否则超出范围.由于len(tasty_fruits)2,索引2超出范围,因此发生运行时恐慌.

您不能将切片索引超出切片的长度,即使容量允许也是如此.如果重新切片,则只能到达超出长度的元素,例如:

tasty_fruits2 := tasty_fruits[:3]
tasty_fruits2[2] = "nectarine" // This is ok, len(tasty_fruits2) = 3
fmt.Printf("%q", tasty_fruits2)
Run Code Online (Sandbox Code Playgroud)

输出:

["orange" "mango" "nectarine"]
Run Code Online (Sandbox Code Playgroud)