1

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:])
}
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189

1 Answers1

3

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.

icza
  • 389,944
  • 63
  • 907
  • 827