问题
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?
回答1:
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.
回答2:
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.
回答3:
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.
来源:https://stackoverflow.com/questions/52250700/why-go-doesnt-report-slice-bounds-out-of-range-in-this-case