为什么会出现以下行为:
a := []int{1, 2, 3}
fmt.Println(a[0:])
fmt.Println(a[1:])
fmt.Println(a[2:])
fmt.Println(a[3:])// doesn't panic - why??
fmt.Println(a[4:])// panics as expected
答案 0 :(得分:4)
对于数组或字符串,如果
0 <= low <= high <= len(a)
,则索引在范围中,否则它们超出范围。对于切片,上部索引边界是切片容量cap(a)
而不是长度。
因此规范允许使用底层数组的len(a)
索引,len(a)
包含(或cap(a)
in切片的情况,在这种情况下具有相同的值)。这就是为什么a[3:]
在你的情况下不会出现恐慌。
但它当然会产生空白,因为:
a[low : high]
表示结果的索引从0
开始,长度等于high - low
,并且由于high
被省略,因此默认为len(a)
len(a) - len(a) = 0
。< / p>
并且(根据规范)使用索引> len(a)
将超出范围因此导致运行时恐慌:
如果索引在运行时超出范围,则会发生run-time panic。
答案 1 :(得分:3)
a[3:]
构建一个空切片,就像一个空数组一样,是一个有效且有用的对象(在所有语言中,不仅仅在Go中)。
空切片仍然指向底层数组,位置和容量,有时可以扩展:
a := []int{1, 2, 3}
emptySlice := a[1:1]
fmt.Println(emptySlice) // []
notEmpty := emptySlice[0:2]
fmt.Println(notEmpty) // [2 3]
另一方面,负长度的切片不一致。它没有任何意义,因而被禁止。
答案 2 :(得分:1)
因为切片中包含0
个元素(3-3
)是完全有效的。但是,-1
元素(3-4
)不是。
此类行为也与其他语言一致。例如,Java:
System.out.println(Arrays.asList(1, 2, 3).subList(0, 3));
System.out.println(Arrays.asList(1, 2, 3).subList(1, 3));
System.out.println(Arrays.asList(1, 2, 3).subList(2, 3));
System.out.println(Arrays.asList(1, 2, 3).subList(3, 3));
System.out.println(Arrays.asList(1, 2, 3).subList(4, 3));
只有最后一个语句失败。