在这种情况下,为什么不报告“切片范围超出范围”? [重复]

This question already has an answer here:

Here's the code to reproduce:

package main

import "fmt"

func main() {
    var v []int
    v = append(v,1)
    v = append(v,v[1:]...)
    fmt.Println("hi", v)

}

v[1] will report index out of range, but v[1:]... won't, why?

</div>

That's how spec defines slice expressions

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

And that's how index expressions for slices are defined

the index x is in range if 0 <= x < len(a), otherwise it is out of range

if x is out of range at run time, a run-time panic occurs

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

For your example:

v[1] panics because it's our of range as per the definition above (because 1 does not qualify the 0 <= x < len(a) reqirement)

v[1:] runs fine because it's identical to v[1:len(v)] and fits the if 0 <= low <= high <= cap(a) requirement.

v[1:] returns a list type. Here an empty list is returned as nothing comes in the slice range specified. Hence no error is thrown.

v[1] is trying to access element explicitly out of bound. No default value is returned hence an error is thrown.

You are allowed to reference an empty slice just past the last element, because this can be useful when implementing things.

Eg.

 s := make([]byte, n)
 // Fill s with something...
 for len(s) > 0 { 
      b := s[0] // Get next byte
      s = s[1:] // Remove it from the slice
      // Deal with byte
 }

...the last removal wouldn't be valid if s[1:1] didn't work on a 1 byte slice.