Anyone knows why the code below runs without panic, it accesses the index one over the length of the string.
import (
"fmt"
)
func main() {
fmt.Println("hi"[2:])
}
Anyone knows why the code below runs without panic, it accesses the index one over the length of the string.
import (
"fmt"
)
func main() {
fmt.Println("hi"[2:])
}
It does not slices "over" the length, 2 is exactly the length (equals to it).
For arrays or strings, the indices are in range if
0 <= low <= high <= len(a)
, otherwise they are out of range.
Since you are slicing a string
, indices are in range if:
0 <= low <= high <= len(a)
This expression:
"hi"[2:]
Since the upper bound is missing, it defaults to length, which is 2, so it is equvivalent to:
"hi"[2:2]
This is perfectly valid by the spec, and it will result in an empty string
. If you change it to "hi"[3:]
, then it will be out of range and result in a compile-time error (as slicing a constant string
can be checked at compile-time).
Reasoning is that the upper bound is exclusive, e.g. a[0:0]
is valid and will be 0-length, a[0:1]
will have a length of 1, a[0:len(a)]
valid and will have the same length as a
.
In case of slices, the lower bound can even be greater than the slice length (but must not exceed the slice capacity). For more details, see Slicing: Out of bounds error in Go.