爲什麼下列行爲發生:爲什麼要允許從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
爲什麼下列行爲發生:爲什麼要允許從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));
只有最後一條語句失敗。
對於數組或字符串,指數在範圍內如果
0 <= low <= high <= len(a)
,否則它們是超出範圍。對於切片,索引上限是切片容量cap(a)
而不是長度。
所以規範允許(在在這種情況下具有相同的值的切片的情況下,或cap(a)
)使用索引到底層陣列,len(a)
包括的len(a)
。這就是爲什麼a[3:]
在你的情況下不會恐慌。
但它會產生當然空片,這是因爲:
a[low : high]
意味着結果具有起始於0
等於high - low
指數和長度,並且自high
被省略,則默認爲len(a)
因此len(a) - len(a) = 0
。
並且還使用索引> len(a)
將超出範圍並因此導致一個在運行恐慌(根據頻譜):
如果索引超出範圍在運行時,一個run-time panic發生。
我應該更清楚這一點。我明白從規格來看這種行爲是可以預料的。但是從程序員的角度來看,似乎應該在約束中添加低
lf215