为什么此代码有效?具体而言,引用切片的行范围为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 - difference between [:n] and [n:]中,解释是底层数组实际上比切片长,因此访问范围a [5:]只是访问更长的数组。但是,当您运行此代码时,您会看到片的长度和容量实际上报告为5。并且,如果您取消对a [5]的引用,您会发现这确实引起了恐慌。
我可以指望这种行为吗,还是遇到了可能在将来的版本中修复的规范/编译器错误?
答案 0 :(得分:0)
这是预期的行为; slice[cap(slice):]
指的是slice
末尾的零长度切片。 Per the spec:
对于数组或字符串,如果0 <=低<=高<= len(a),则索引在范围内,否则它们超出范围。对于切片,索引的上限是切片容量cap(a)而不是长度。
请注意,它是<= len(a)
,而不是< len(a)
;规格允许使用等于长度/容量的索引。