为什么这样做有效,我在最大索引后切片了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

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).