iTranslated by AI
iota is not always zero when it first appears
Another quick tip.
In Section 3.6.1, "The iota Constant Generator," of The Go Programming Language, which was discussed during the "16th 'The Go Programming Language' Online Reading Circle", the book states:
In a const declaration, the value of iota begins at zero and increments by one for each item in the sequence.
However, Yoshiki Shibata, the translator and organizer of the reading circle, provided an explanation regarding this point. This post is about that.
Originally, const has a feature where the same value as the preceding constant is set when written this way:
package main
import "fmt"
const (
one = 1
two
three
four
)
func main() {
fmt.Println(one, two, three, four)
// Output:
// 1 1 1 1
}
By combining this property with the iota constant generator, you can set values that increment one by one.
package main
import "fmt"
const (
one = 1 + iota
two
three
four
)
func main() {
fmt.Println(one, two, three, four)
// Output:
// 1 2 3 4
}
So, is the initial value of iota always zero? It’s a bit more nuanced than that. For example:
package main
import "fmt"
const (
zero = "0"
one = 1
two
three
four = iota
)
func main() {
fmt.Println(zero, one, two, three, four)
// Output:
// 0 1 1 1 4
}
If you write it this way, the value of iota when it appears is 4. In other words, iota is being counted from the start, even before it (apparently[1]) appears.
If you assume that the value of iota is always zero when it appears and accidentally write code like this:
package main
import "fmt"
const (
one = 1 + iota
two
three
four
zero = iota
)
func main() {
fmt.Println(zero, one, two, three, four)
// Output:
// 4 1 2 3 4
}
... zero will not be zero, resulting in an unexpected value. It's embarrassing, but I actually got stuck on this pattern in the past (it didn't pass the tests, and I spent some time wondering why).
To avoid this:
package main
import "fmt"
const (
one = 1 + iota
two
three
four
)
const (
zero = iota
)
func main() {
fmt.Println(zero, one, two, three, four)
// Output:
// 0 1 2 3 4
}
... you should wrap each iota sequence in a separate const declaration like this.
-
Strictly speaking,
iotais not a counter. I have summarized this in my article "Writing properly about the iota constant generator" (Japanese text). ↩︎
Discussion