如何解决片可以访问超出范围的另一个片,但索引超出范围会引起恐慌
我的代码:
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
我的问题:
为什么即使索引4超出了长度为3的b[4:7]
的索引4,但访问b
的索引4却超出范围,为什么仍可以访问b[4]
?什么Go语言规则解释了这种行为?
解决方法
相关规则:Spec: Index expressions和Spec: Slice expressions。
简而言之:建立索引时,索引必须小于 length 。切片时,上限索引必须小于或等于容量。
索引时:a[x]
如果
x
,索引0 <= x < len(a)
在范围内 ,否则超出范围
切片时:a[low: high]
对于数组或字符串,如果
0 <= low <= high <= len(a)
,则索引在范围内,否则,它们在范围之外。 对于切片,索引的上限是切片容量cap(a)
而不是长度。
执行此操作时:
b := a[1:4]
b
是一个切片,与a
共享后备阵列,b
的长度为3
,容量为9
。因此,以后将b
切成甚至超过其长度,直至达到其容量9
都是完全有效的。但是,在编制索引时,您始终只能索引切片长度所覆盖的部分。
我们使用索引来访问切片或数组的当前元素,如果要创建数组或切片的片段,或者如果要扩展,则使用切片。扩展它意味着我们想要更大的一部分(但仍由后备阵列覆盖)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。