Reputation: 1086
I have
type DocId int
func foo(documents []String) {
for i := range documents {
id := DocId(i)
...
}
}
How do I get rid of the explicit conversion line? DocIds are meant to be the type that indexes individual documents.
What I want is more like:
func foo(documents []String) {
for id := range documents {
... // id gets used as the DocId that it damn well *IS*
}
}
Which gives me 'invalid operation: ... (mismatched types int and DocId)' when I attempt to use the id from range as a DocId, even though DocId is an int.
Upvotes: 3
Views: 1459
Reputation: 54117
Here is another idea which you may or may not like - use a map
since maps can have keys of custom types unlike slices.
type DocId int
func foo(documents map[DocId]string) {
for id := range documents {
// do stuff with id and documents[id]
}
}
Upvotes: 3
Reputation: 1328652
Only untyped constant can be automatically converted in the right type.
You can find examples where the cast is not needed like in this thread, for untyped constant. From the specs:
if one operand is an untyped constant and the other operand is not, the constant is converted to the type of the other operand
But here, range
explicitly assign iteration values to the corresponding iteration variables (i int, T a[i])
, which makes i
and int
. (from spec "For statement")
For all the other case, an explicit cast is required.
The "Conversion" section of the specs doesn't mention an "automatic" type conversion (as opposed to automatic interface conversion, which happens all the time: interface{}
).
This thread adds
type A int
type B int
...
var a A = 5
var b B = a // Compiler ERROR!!!!!!
Essentially, since (nearly) all types are unique, even two types with the same underlying representation and primitive operations are unassignable without a cast. [...]
This makes the language type-safe by forcing you to explicitly tell the compiler when you want the conversion to happen.
Upvotes: 4