What is iota, and how is it used to build enumerated constants?

4 minbeginnergoiotaconstantsenums

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").

Related Resources