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

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

问题描述:

I was playing around with slices, and I found something that I can't explain. I create a string of total length 10 (index ranges from 0 to 9) and then I create a slice from it specifying one past the max index and it does not panic. It will panic if I go more than one past the last index. What am I not understanding please?

I have investigated with integer slices as well thinking there might be something odd about strings, but it showed the same behavior.

Here is an example: I expected a failure at x:= str[10:].

package main

import "fmt"

func main() {

    var str = "attribute="

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

    for k, v := range []byte(str) {
        fmt.Printf("%d, %x
", k, v)
    }

}

Playground: https://play.golang.org/p/Z-3YvTx3-s6

Output:

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

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

我对整数切片进行了调查,并认为字符串可能有些奇怪,但它表现出相同的行为。 p>

这里是一个示例:我预期在 x:= str [10:] code>时失败。 p>

  package main 
 
import“  fmt“ 
 
func main(){
 
 var str =” attribute =“ 
 
x:= str [10:] 
 fmt.Printf(” x的类型为%T 
“,x  )
 //fmt.Printf("x为%T,x的长度为%d 
“,x,len(x))
 
 for k,v:= range [] byte(str)  {
 fmt.Printf(“%d,%x 
”,k,v)
} 
 
} 
  code>  pre> 
 
 

游乐场: https://play.golang.org/p/Z-3YvTx3-s6

输出: p>

  x的类型为字符串
0、61 
1、74 
2、74 
3、72 
4,  69 
5、62 
6、75 
7、74 
8、65 
9、3d 
  code>  pre> 
  div>

It's in the spec. Having low or high equal to the length is allowed.

For arrays or strings, the indices are in range if 0 <= low <= high <= len(a), otherwise they are out of range.

As to "why is this not an error": you can visualize the slicing operation as cutting between the elements. Like this:

│   a   t   t   r   i   b   u   t   e   =    │
│ ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑   ↑  │
│ 0   1   2   3   4   5   6   7   8   9   10 │

Technically slice point 10 is still within bounds, but it has no elements after it. That's why [10:] results in an empty string (that, or because there are no elements between low and high). This works the same way in ruby, for example. Maybe other languages too.

From the language specification for Slice expressions:

For a string, array, pointer to array, or slice a, the primary expression

a[low : high]

constructs a substring or slice. The indices low and high select which elements of operand a appear in the result.

. . .

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.

So, both low and high can have the values 0 and len(a).