这个问题在这里已有答案:
这是重现的代码:
package main
import "fmt"
func main() {
var v []int
v = append(v,1)
v = append(v,v[1:]...)
fmt.Println("hi", v)
}
v[1]
将报告index out of range
,但v[1:]...
不会,为什么?
这就是spec定义切片表达式的方式
对于数组或字符串,如果0 <= low <= high <= len(a),则索引在范围内,否则它们超出范围。对于切片,上限索引是切片容量上限(a)而不是长度。
https://golang.org/ref/spec#Slice_expressions
这就是定义切片的索引表达式的方式
如果0 <= x <len(a),则索引x在范围内,否则它超出范围
如果x在运行时超出范围,则会发生运行时混乱
https://golang.org/ref/spec#Index_expressions
对于你的例子:
qazxsw poi恐慌,因为它超出了上面的定义范围(因为qazxsw poi不符合v[1]
要求)
1
运行正常,因为它与0 <= x < len(a)
相同,符合v[1:]
要求。
v [1:]返回列表类型。这里返回一个空列表,因为指定的切片范围内没有任何内容。因此不会抛出任何错误。
v [1]试图明确地访问元素超出范围。未返回默认值,因此会引发错误。
您可以在最后一个元素之后引用一个空切片,因为这在实现时很有用。
例如。
v[1:len(v)]
...如果s [1:1]在1字节切片上不起作用,则最后一次删除无效。