In the code below, (2) is OK, and (3) is a runtime error for what reason? The Go version is "go1.11 darwin/amd64".
package main
import "fmt"
funcmain(){
a: = "a"
fmt.Println(a[:len(a)])//(1) "a"
fmt.Println(a[len(a):])//(2)"
// fmt.Println(a[len(a)])//(3)panic-index out of range
// fmt.Println(a[len(a)+1:])//(4)panic-slice bound out of range
}
I have rarely used Go language, but
0
to len(a)-1
It's the same when you say .
I think it would be easier to understand if there were more than one element.
package main
import(
"fmt"
)
funcmain(){
a: = "abc"
fmt.Println(len(a))//->3
fmt.Println(a[0])//->97('a')
fmt.Println(a[1])//->98('b')
fmt.Println(a[2])//->99('c')
// fmt.Println(a[3]) // panic:runtime error:index out of range
fmt.Println(a[0:])//->abc
fmt.Println(a[:3])//->abc
fmt.Println(a[0:3])//->abc
fmt.Println(a[1:])//->bc
fmt.Println(a[1:3])//->bc
fmt.Println(a[2:])//->c
fmt.Println(a[2:3])//->c
fmt.Println(a[3:])//->
fmt.Println(a[3:3])//->
// fmt.Println(a[4:]) // panic:runtime error:slice bound out of range
}
This is how a
(len(a)==3
) indexes are assigned.
| 'a' | 'b' | 'c' | Nothing
[0] [1] [2] [3]
a[len(a)]
(==a[3]
) is an error, of course.
Then, on the contrary, a[:len(a)]
and a[len(a):]
do not fail because there is a second rule above.
a[:len(a)]
is the same as a[0:3]
when len(a)==3
.
| 'a' | 'b' | 'c' | Nothing
[0]← From here
[3]← Up to one serving here
a[3]
has no element, but the range is up to one before it, so it means "abc".
Of course, if 3
cannot be specified, the range that represents "all to the end" will not be explicitly written.
Also, since a[0:3]
represents "abc"
, a[1:3]
represents "bc"
, and a[2:3]
represents "c"
, is it very natural that a[3:3]
represents an empty string? (You may not think until you get used to it...)
So it's not so much for humans as for the convenience of machines.where 3
is a valid value (although the endpoint must be the same) when representing the starting point of the range.
a[0:]
| 'a' | 'b' | 'c' | Nothing
[0]← All from here (`abc``)
a [3:]
| 'a' | 'b' | 'c' | Nothing
[3]← All from here (``````)
In the case of your example, len(a)==1
, so it may not make sense, but it's almost the same.
a[:0](==a[:len(a)]
| 'a' | Nothing
[1]← All before this ("a")
a[0:](==a[len(a):]
| 'a' | Nothing
[1]← All from here ("")
It's more convenient to specify a range that's hard to understand, but if you gain experience in this way, you'll see it naturally.
Please let me know if there is anything else that is hard to understand.
This is not the answer, but I looked into how it works on the source code.
The slice processing is done here at .
slice computers the slice v[i:j:k] and returns ptr, len, and cap of result.i,j,k may binil, in which case they are set to their default value.
As you can see in the comments, a[len(a):]
is treated as a[len(a):len(a)]
for bound checking.In this case, a
is a string, so s.boundsCheck(i,j,ssa.BoundsSliceB,bound)
will eventually run.
case t.IsString():
ptr = s.newValue1 (ssa.OpStringPtr, types.NewPtr (types.Types [TUINT8]), v)
len=s.newValue1 (ssa.OpStringLen, types.Types [TINT], v)
cap=len
:
// Set default values
:
if j == nil {
j=len
}
three —= true
ifk == nil {
three=false
k = cap
}
// Panic if slice indications are not in bounds.
:
if three {
:
} else{
if j!=k{
:
}
i=s.boundCheck(i,j,ssa.BoundsSliceB,bound)
}
ssa.BoundsSliceB
is the operational code for boundary checks, but is defined here in .
type BoundsKinduint8
const(
BoundsIndex BoundsKind = iota//indexing operation, 0<=idx<len failed
:
BoundsSliceB//2-arg slicing operation, 0<=low<=high failed
The decision criteria are 0<=low<=high
and both low
, high
are len(a)
, so it is determined to be within the boundary.
If a[len(a)+1:]
, low=len(a)+1
, high=len(a)
, it becomes low>high
, and you get stuck in the boundary check (panic(bounds out of range)
).
If the decision criteria were 0<=low<high
, then a[len(a):]
would have caused panic.
Incidentally, for index access such as a[len(a)]
, it is checked with BoundsIndex
, so 0<=idx<len
is the criterion (a[len(a)]
is index of code>).
© 2024 OneMinuteCode. All rights reserved.