Go specification gives the rules for index expression a[x]
:
If
a
is not a map:
- the index x must be of integer type or an untyped constant
- a constant index must be non-negative and representable by a value of type int
- a constant index that is untyped is given type int
- the index x is in range if 0 <= x < len(a), otherwise it is out of range
What does exactly the third rule (a constant index that is untyped is given type int ) mean? Doesn't a valid expression a[1.0]
contradict that rule?
CodePudding user response:
Every value used at runtime must have a type. If you use an untyped constant, it will be converted to a typed value such as in this example:
fmt.Printf("%T %v", 1, 1)
1
is an untyped constant, but when passed to fmt.Printf()
, it must be converted to a typed value. In the example above, its default type will be used which is int
, so the above example prints int 1
.
- a constant index that is untyped is given type
int
This means that if you use a constant value for the index that is untyped (it has no type), then int
will be used when the constant is converted to a typed value.
For example:
s := []int{1, 2, 3}
fmt.Println(s[1])
Here the untyped constant 1
is used as the index, so it will be converted / used as int
.
A counter-example:
fmt.Println(s[int32(1)])
Here s
is indexed with a typed value int32(1)
. This is valid because int32
is an integer type.
The rule just says that if you use an untyped constant, then it will be given int
type, and not int32
for example.
This may seem obvious when using integer literals, but not when using other kind of literals, such as rune literals.
The following is also valid:
fmt.Println(s['\x00'])
The above example uses a rune literal '\x00'
as the index, which is also an untyped constant but it has a different default type. Rune literals have default type rune
which is an alias for int32
. The quoted indexing rule states that in this case the index will be of type int
and not int32
.
CodePudding user response:
It doesn't. 1.0
and 1
are the same number (mathematically), so the untyped constant 1.0
can be given a type int
.
If you'll, however, try to specify a[1.5]
, you'll get an error, since 1.5
is not an integer.