I have a string
, and when I want to get the value at i
index it panics, but when I slice out of the same string
keeping lower index value as length then it doesn't panic. Wanted to know how 1 and 2 differs?
func main() {
str := "a"
fmt.Println(str[1]) // 1 this panics
fmt.Println(str[1:]) // 2 this doesn't
}
TLDR; In an index expression the index must be less than the length, and in a slice expression the length is a valid index.
In an index expression the index must be in range, else it panics. The index is in range if 0 <= i < length
. Quoting from the spec:
In the index expression
a[x]
...If
a
is not a map:
- the index
x
is in range if0 <= x < len(a)
, otherwise it is out of range
And:
For a of string type:
- if
x
is out of range at run time, a run-time panic occurs
Your str
string variable stores a string
value which has a single byte: 'a'
. Indexing starts at zero, so that single byte has index 0
. Its length is 1
, so there is no element at index 1
.
In a slice expression:
a[low : high]
For arrays or strings, the indices are in range if
0 <= low <= high <= len(a)
, otherwise they are out of range.
In a slice expression the length is a valid index. So in your case indexing str
like str[1:]
will result in an empty string: ""
:
In a slice expression
a[low : high]
...The result has indices starting at
0
and length equal tohigh - low
.A missing
low
index defaults to zero; a missinghigh
index defaults to the length of the sliced operand.
So str[1:]
is the same as str[1:len(str)]
which is str[1:1]
. The result string will have a length of high - low = 1 - 1 = 0
: the empty string
.