What is iota, and how is it used to build enumerated constants?
Quick Answer
iota is a predeclared identifier that resets to 0 at the start of each const block and increments by 1 for each subsequent ConstSpec line within that block. It's Go's mechanism for building enum-like sequences, since Go has no native enum keyword. A typical pattern defines a named type plus a const block using iota: type Weekday int; const (Sunday Weekday = iota; Monday; Tuesday; ...). iota can also be used in expressions to generate non-sequential patterns, like powers of two for bitmask flags (1 << iota).
Detailed Answer
Go has no enum keyword. iota plus a typed const block is the idiomatic substitute.
Basic sequential enum
type Weekday int
const (
Sunday Weekday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
Each line without an explicit value repeats the previous line's expression, with iota incremented for that line.
Giving enum values a String() method
func (d Weekday) String() string {
names := [...]string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}
return names[d]
}
fmt.Println(Tuesday) // "Tuesday", because fmt calls String() automatically
Using iota for bitmask flags
type Permission uint8
const (
Read Permission = 1 << iota // 1 << 0 = 1
Write // 1 << 1 = 2
Execute // 1 << 2 = 4
)
perms := Read | Write // 3
fmt.Println(perms&Write != 0) // true
A common gotcha: skipping a value
const (
_ = iota // skip 0 with a blank identifier
KB = 1 << (10 * iota) // iota=1: 1<<10
MB // iota=2: 1<<20
GB // iota=3: 1<<30
)
The blank identifier _ consumes an iota value without creating a name, a common trick when you want to skip the zero value on purpose (often because the zero value should mean "unset").