iota
suggest changeiota
makes it easy to declare sequentially growing numeric constants:
const (
Low = iota
Medium
High
)
fmt.Printf("Low: %d\nMedium: %d\nHigh: %d\n", Low, Medium, High)
Low: 0
Medium: 1
High: 2
iota
sets the value of Low
to 0 and instructs the compiler that the following constants have increasing numeric values.
Creating bitmask values with iota
Iota can be very useful when creating a bitmask. For instance, to represent the state of a network connection which may be secure, authenticated, and/or ready, we might create a bitmask like the following:
const (
Secure = 1 << iota // 0b001
Authn // 0b010
Ready // 0b100
)
ConnState := Secure | Authn // 0b011: Connection is secure and authenticated, but not yet Ready
fmt.Printf(`Secure: 0x%x (0b%03b)
Authn: 0x%x (0b%03b)
ConnState: 0x%x (0b%03b)
`, Secure, Secure, Authn, Authn, ConnState, ConnState)
Secure: 0x1 (0b001)
Authn: 0x2 (0b010)
ConnState: 0x3 (0b011)
Skipping values
The value of iota
is still incremented for every entry in a constant list even if iota is not used:
const ( // iota is reset to 0
a = 1 << iota // a == 1
b = 1 << iota // b == 2
c = 3 // c == 3 (iota is not used but still incremented)
d = 1 << iota // d == 8
)
fmt.Printf("a: %d, b: %d, c: %d, d: %d\n", a, b, c, d)
a: 1, b: 2, c: 3, d: 8
It will also be incremented even if no constant is created at all, meaning the empty identifier can be used to skip values entirely:
const (
a = iota // a = 0
_ // iota is incremented to 1
b // b = 2
)
fmt.Printf("a: %d, b: %d\n", a, b)
a: 0, b: 2
Using iota
in an expression list
Because iota
is incremented after each ConstSpec
, values within the same expression list will have the same value for iota
:
const (
bit0, mask0 = 1 << iota, 1<<iota - 1 // bit0 == 1, mask0 == 0
bit1, mask1 // bit1 == 2, mask1 == 1
_, _ // skips iota == 2
bit3, mask3 // bit3 == 8, mask3 == 7
)
fmt.Printf("bit0: %d, mask0: 0x%x\n", bit0, mask0)
fmt.Printf("bit3: %d, mask3: 0x%x\n", bit3, mask3)
bit0: 1, mask0: 0x0
bit3: 8, mask3: 0x7
Using iota
in an expression
iota
can be used in expressions, so it can also be used to assign values other than simple incrementing integers starting from zero. To create constants for SI units, use this example from Effective Go:
type ByteSize int
const (
_ = iota // ignore first value by assigning to blank identifier
KB ByteSize = 1 << (10 * iota)
MB
GB
TB
PB
)
fmt.Printf("KB: %d\n", KB)
KB: 1024