The smallest thing in Go: iota, enums, and magic constants
What is the smallest thing in Go? Well, I’m glad you asked!
iota and enums
We often define constants in Go to enumerate a list of possible values that something could take (sometimes called an “enum” for short). For example, suppose we’re writing an astronomy program, and we want to be able to distinguish between different kinds of night-sky objects:
const (
Planet = 0
Star = 1
Comet = 2
Galaxy = 3
// ...and so on
)The specific numbers 0, 1, 2… aren’t important here. They’re just arbitrary values we can compare things against:
if object.Kind == Planet {
// it's a planet!
}Using iota with
const
It’s hard to maintain a long list of numbers like this by hand,
though. That’s where iota comes in. It’s a kind of magical,
ever-increasing value we can use to assign arbitrary numbers to
constants:
const (
Planet = iota // 0
Star // 1
Comet // 2
Galaxy // 3
// ...
)We’re effectively assigning iota to every constant in
the list, but Go lets us omit all but the first “= iota”.
Very handy!
Starting iota at 1
And we can use iota in more complicated expressions,
too. For example, if we want the successive values to start at 1 instead
of 0:
const (
January = iota+1
February
March
// ...
)Here, the value of January will be 1,
February will be 2, and so on.
iota skips comments
By the way, you can put comments or blank lines in your constant
block, and it won’t affect the values of iota:
const (
// fermions
Electron = iota // 0
Neutron // 1
Proton // 2
// bosons
Photon // 3
Gluon // 4
)iota, flags, and
bitmasks
Another common use for iota is creating values for
bitmasks. A bitmask is something you can compare against a
binary number to see if a particular bit in that number is 1 or 0. When
particular bit values are used in this way, they’re sometimes called
flags, and the number containing them is called a
bitfield (well, well).
For example:
const (
Bit0 = 1 << iota // 1
Bit1 // 2
Bit2 // 4
// ...
)The << operator shifts the bits of a number to the
left by the given number of places. Since iota increases by
one for each successive constant, that means the shift factor increases
by one too, so the values assigned to the constants keep on
doubling.
Now we can do a bitwise comparison of these mask values against some number we’re interested in:
v := 0b00000010
if v&Bit1 != 0 {
fmt.Println("Looks like bit 1 is set!")
}
// Output:
// Looks like bit 1 is set!Now you know all about iota in Go! Have fun with it.
Want to learn more? Check out my book introducing Go to beginners, The Deeper Love of Go.




