为什么在go中切片比索引1的长度多但不超过长度

package main

import (
    "fmt"
)

func main() {
    s:= []int{1,2}
    fmt.Println(s[0:]) // this is expected
    fmt.Println(s[1:]) // this is expected
    fmt.Println(s[2:]) // this wondering why i didn't recieve slice bounds out of range error
    fmt.Println(s[3:]) // here i recieve the error
}

Can some one explain why s[2:] returns empty slice [] but s[3:] errors out. i thought s[2:] should error out too.

Based on The Go Programming Language Specifications

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.

https://golang.org/ref/spec#Slice_expressions

s[3:] gives an error because your low index (which is 3) is greater than len(s) (which is 2) and therefore out of range

The indices low and high select which elements of operand a appear in the result. The result has indices starting at 0 and length equal to high - low.

s[2:] gives you an empty slice because your low index (which is 2) and your high index (which defaults to 2 by golang spec), which results in a slice with a length of 0 (high - low)

0     1     2    n-1    n
|_____|_____|_..._|_____|
 s[0]  s[1]        s[n-1]

I found this explanation from a golang book. Above is the indices, and below is the elements.

We could see that n is also a valid index when getting subslices, and this could explain why s[a:b]={s[a], s[a+1], ... , s[b-1]}, and s[n:]=s[n:n]={}