切片可以访问另一个超出范围的切片,但索引超出范围会导致恐慌

我的代码:


package main


import (

    "fmt"

)


func main() {

    a := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}

    b := a[1:4]

    fmt.Println("a:", a)

    fmt.Println("b:", b)

    

    // Works fine even though c is indexing past the end of b.

    c := b[4:7]

    fmt.Println("c:", c)

    

    // This fails with panic: runtime error: index out of range [4] with length 3

    // d := b[4]

}

输出:


a: [0 1 2 3 4 5 6 7 8 9]

b: [1 2 3]

c: [5 6 7]

如果我取消注释包含 的行d := b[4],则会导致此错误:


panic: runtime error: index out of range [4] with length 3

我的问题:


为什么b[4:7]即使索引 4 超出b长度为 3 的范围也可以访问,但不能访问b[4]?什么 Go 语言规则解释了这种行为?


眼眸繁星
浏览 131回答 1
1回答

30秒到达战场

相关规则:Spec: Index 表达式和Spec: Slice 表达式。简而言之:索引时,索引必须小于长度。切片时,上索引必须小于或等于容量。索引时:a[x]如果,x则索引在范围内0 <= x < len(a),否则超出范围切片时:a[low: high]对于数组或字符串,索引在范围内if&nbsp;0 <= low <= high <= len(a),否则超出范围。对于切片,索引上限是切片容量cap(a)而不是长度。当你这样做时:b&nbsp;:=&nbsp;a[1:4]b将是一个与 共享后备数组的切片a,其b长度为3,其容量为9。因此,稍后切片b甚至超出其长度也是完全有效的,直到其容量为9.&nbsp;但是在索引时,您始终可以仅索引切片长度所覆盖的部分。我们使用索引来访问切片或数组的当前元素,如果我们想要创建数组或切片的片段,或者想要扩展它,我们会使用切片。扩展它意味着我们想要更大的部分(但仍然被支持数组覆盖)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go