go - 去切片-结束后不要惊慌
问题描述
为什么这段代码有效?具体来说,引用切片范围 a[5:] 并返回零长度切片的行?长度和容量都报告为 5,但引用第六个不存在的元素不会引起恐慌:
package main
import (
"fmt"
)
func main() {
a := []int{1, 2, 3, 4, 5}
fmt.Println(a, "Len(a)=", len(a), "Cap(a)=", cap(a))
fmt.Println(a[4]) // Works as expected
// fmt.Println(a[5]) // XXX-runtime error:index out of range
fmt.Println(a[5:]) // Works--returns a zero-length slice--but why?
a = append(a[:4], a[5:]...)
fmt.Println(a, "Len(a)=", len(a), "Cap(a)=", cap(a))
}
去游乐场: https: //play.golang.org/p/7evt4Y0ADD3
在Go Slice - [:n] 和 [n:] 之间的区别中,解释是底层数组实际上比切片长,因此访问范围 a[5:] 只是访问更长的数组。但是,当您运行此代码时,您会看到切片的长度和容量实际上报告为 5。如果您取消注释对 a[5] 的引用,您会看到这确实会引起预期的恐慌。
我可以指望这种行为还是我遇到了可以在未来版本中修复的规范/编译器错误?
解决方案
这是预期的行为;slice[cap(slice):]
指的是 结尾处的零长度切片slice
。根据规范:
对于数组或字符串,如果 0 <= low <= high <= len(a),则索引在范围内,否则超出范围。对于切片,索引上限是切片容量 cap(a) 而不是长度。
请注意,它是<= len(a)
,不是< len(a)
;根据规范,允许使用等于长度/容量的索引。
推荐阅读
- r - R语言:用它自己的修改版本替换文本
- python - 对 gevent flask api 的多次调用未并行处理
- c++ - C++ Windows 显示无框图像
- flutter - 在路线更改之间弹出路线?
- unity3d - 我的模型表面上的这些伪影是什么?如何删除它们?
- python - 尝试加载crispy_forms 时引发 ImportError
- java - 你如何计算数独中某个空间的有效数字列表?
- java - 使用 OOP 实现我的点和线类 - 错误:空指针异常
- r - R - 如何将文件从一个位置复制并粘贴到 s3 存储桶中的另一个位置(使用 aws.s3)?
- ios - 可滚动的全屏视图 swift