为什么 go 允许从 len(slice) 切片?
Why does go allow slicing from len(slice)?
为什么会出现以下行为:
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
a[3:]
构建一个空切片,就像一个空数组一样,它是一个有效且有用的对象(在所有语言中,不仅仅是在 Go 中)。
空切片也仍然指向底层数组、位置和容量,有时可以扩展:
a := []int{1, 2, 3}
emptySlice := a[1:1]
fmt.Println(emptySlice) // []
notEmpty := emptySlice[0:2]
fmt.Println(notEmpty) // [2 3]
另一端,长度为负的切片不一致。它没有任何意义,因此被禁止。
因为切片中有 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));
只有最后一条语句失败了。
For arrays or strings, the indices are in range if 0 <= low <= high <= len(a)
, otherwise they are out of range. For slices, the upper index bound is the slice capacity cap(a)
rather than the length.
因此规范允许使用索引最多 len(a)
的底层 array, len(a)
included (或者 cap(a)
在切片的情况下,在这种情况下具有相同的值)。这就是为什么 a[3:]
在你的情况下不会恐慌。
但它当然会产生一个空切片,因为:
a[low : high]
表示结果的索引从 0
开始,长度等于 high - low
并且由于 high
被省略,因此默认为 len(a)
因此 len(a) - len(a) = 0
.
而且(根据规范)使用索引 > len(a)
将超出范围 并因此导致运行时恐慌:
If the indices are out of range at run time, a run-time panic occurs.
为什么会出现以下行为:
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
a[3:]
构建一个空切片,就像一个空数组一样,它是一个有效且有用的对象(在所有语言中,不仅仅是在 Go 中)。
空切片也仍然指向底层数组、位置和容量,有时可以扩展:
a := []int{1, 2, 3}
emptySlice := a[1:1]
fmt.Println(emptySlice) // []
notEmpty := emptySlice[0:2]
fmt.Println(notEmpty) // [2 3]
另一端,长度为负的切片不一致。它没有任何意义,因此被禁止。
因为切片中有 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));
只有最后一条语句失败了。
For arrays or strings, the indices are in range if
0 <= low <= high <= len(a)
, otherwise they are out of range. For slices, the upper index bound is the slice capacitycap(a)
rather than the length.
因此规范允许使用索引最多 len(a)
的底层 array, len(a)
included (或者 cap(a)
在切片的情况下,在这种情况下具有相同的值)。这就是为什么 a[3:]
在你的情况下不会恐慌。
但它当然会产生一个空切片,因为:
a[low : high]
表示结果的索引从 0
开始,长度等于 high - low
并且由于 high
被省略,因此默认为 len(a)
因此 len(a) - len(a) = 0
.
而且(根据规范)使用索引 > len(a)
将超出范围 并因此导致运行时恐慌:
If the indices are out of range at run time, a run-time panic occurs.