为什么这样做有效,我在最大索引后切片了1个,却没有收到错误?

时间:2019-04-14 18:39:37

标签: go

我正在玩切片,但发现了一些我无法解释的内容。我创建了一个总长度为10的字符串(索引范围从0到9),然后从中创建一个切片,该切片指定了一个超出最大索引的值,并且它不会出现混乱。如果我超过上一个指数不止一个,那将会恐慌。请问我不明白什么?

我研究了整数切片,并认为字符串可能有些奇怪,但它表现出相同的行为。

这里是一个示例:我预计在x:= str[10:]上会失败。

package main

import "fmt"

func main() {

    var str = "attribute="

    x := str[10:]
    fmt.Printf("type of x is %T\n", x)
    //fmt.Printf("x is a %T and length of x is %d\n", x, len(x))

    for k, v := range []byte(str) {
        fmt.Printf("%d, %x\n", 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

2 个答案:

答案 0 :(得分:3)

它在the spec中。允许lowhigh等于长度。

  

对于数组或字符串,如果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:]产生空字符串的原因(或者是因为lowhigh之间没有元素)。例如,这在红宝石中的工作方式相同。也许还有其他语言。

答案 1 :(得分:2)

根据Slice expressions的语言规范:

  

对于字符串,数组,指向数组的指针或切片a,主表达式

a[low : high]
     

构造子字符串或切片。索引低和索引高选择在结果中出现哪些操作数元素。

     

。   。   

     

对于数组或字符串,如果0 <=低<=高<= len(a),则索引在范围内,否则它们超出范围。对于切片,索引的上限是切片容量cap(a)而不是长度。

因此,高值和低值都可以具有值0len(a)