我在玩切片,我发现了一些我无法解释的东西。我创建了一个总长度为 10 的字符串(索引范围从 0 到 9(,然后我从中创建一个切片,指定一个超过最大索引的切片,它不会惊慌失措。如果我超过最后一个索引不止一个,它会惊慌失措。请问我不明白什么?
我也用整数切片进行了调查,认为字符串可能有些奇怪,但它显示出相同的行为。
这是一个例子:我预计x:= str[10:]
会失败。
package main
import "fmt"
func main() {
var str = "attribute="
x := str[10:]
fmt.Printf("type of x is %Tn", x)
//fmt.Printf("x is a %T and length of x is %dn", x, len(x))
for k, v := range []byte(str) {
fmt.Printf("%d, %xn", k, v)
}
}
游乐场:https://play.golang.org/p/Z-3YvTx3-s6
输出:
type of x is string
0, 61
1, 74
2, 74
3, 72
4, 69
5, 62
6, 75
7, 74
8, 65
9, 3d
它在规范中。允许low
或high
等于长度。
对于数组或字符串,如果
0 <= low <= high <= len(a)
索引,则在范围内,否则它们超出范围。
至于"为什么这不是错误":您可以将切片操作可视化为元素之间的切割。喜欢这个:
│ a t t r i b u t e = │
│ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑ │
│ 0 1 2 3 4 5 6 7 8 9 10 │
从技术上讲,切片点 10 仍在范围内,但它之后没有元素。这就是为什么[10:]
导致空字符串的原因(或者因为low
和high
之间没有元素(。例如,这在红宝石中的工作方式相同。也许其他语言也是如此。
从 Slice 表达式的语言规范:
对于字符串、数组、指向数组的指针或切片 a,主表达式
a[low : high]
构造子字符串或切片。低和高索引选择在结果中显示操作数 a 的哪些元素。
. . .
对于数组或字符串,如果 0 <= 低 <= 高 <= len(a(,则索引在范围内,否则它们超出范围。对于切片,索引上限是切片容量上限 (a( 而不是长度。
因此,低和高都可以具有值 0
和 len(a)
.