Why go doesn't report “slice bounds out of range” in this case? [duplicate]

这一生的挚爱 提交于 2020-06-23 18:48:31

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!