★ Ultimate Visual Guide to Go Enums and iota
Go enums and iota — Full of tips and tricks with runnable code examples.
Important: In this tutorial, you’ll learn how to use the enums without iota in the first section — After that, you’ll also learn about iota and the other helper tools as well after the first section. So, learn to crawl first, then walk then run!

What is an Enum? ★
An enum groups related constants together in one type.
Example enums:
- Timezones: EST, CST…
- T-shirt Sizes: Small, Medium, Large
- Server Statuses: Unknown, Running, Stopped, Resumed

Why do we need enums?
- Grouping and expecting only some related values
- Sharing common behavior
- Avoids using invalid values
- To increase the code readability and the maintainability

How can you imitate an enum in Go?
For example, suppose that you want to create an enum for the weekdays.


★ First: Declare a new custom type: Weekday
Weekday will unify our enum constants under a common type.
type Weekday int

★ Second: Declare related constants for Weekday
Assign them different numeric values, so, they don’t clash.
const (
Sunday Weekday = 0
Monday Weekday = 1
Tuesday Weekday = 2
Wednesday Weekday = 3
Thursday Weekday = 4
Friday Weekday = 5
Saturday Weekday = 6
)fmt.Println(Sunday) // prints 0fmt.Println(Saturday) // prints 6

Creating common behavior for Weekday enum
You attach methods to a type to define its behaviors.
The attached methods will be the inseparable parts of Weekday, and shared among Weekday constants.


★ String() method:
func (day Weekday) String() string {
// declare an array of strings
// ... operator counts how many
// items in the array (7) names := [...]string{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"} // → `day`: It's one of the
// values of Weekday constants.
// If the constant is Sunday,
// then day is 0.
//
// prevent panicking in case of
// `day` is out of range of Weekday if day < Sunday || day > Saturday {
return "Unknown"
} // return the name of a Weekday
// constant from the names array
// above.
return names[day]
}
★ Let’s try:
fmt.Printf("Which day it is? %s\n", Sunday)
// Which day it is? Sunday


★ Weekend() method:
func (day Weekday) Weekend() bool {
switch day {
case Sunday, Saturday: // If day is a weekend day
return true default: // If day is not a weekend day
return false
}
}
Convention: Instead of IsWeekend, we just use Weekend.
★ Let’s try:
fmt.Printf("Is Saturday a weekend day? %t\n", Saturday.Weekend())
// Is Saturday a weekend day? true


Creating names automatically

You can use Rob Pike’s Stringer to create String method automatically.
# install the stringer tool
go get -u -a golang.org/x/tools/cmd/stringer# grab the code from here
# and save it in weekday.go
# inside your $GOPATH/src/enums# then, run stringer to create
# enum names automatically
stringer -type Weekday weekdays.go


How to use iota?
Iota expression is repeated by the other constants until another assignment or type declaration shows up.


Let’s see how iota ticks tocks
iota increases by 1 after each line except empty and comment lines.


When not to use iota
const (
RestartMarkerReply = 110
ServiceReadyInNMinutes = 120
CommandOK = 200
CommandNotImplemented = 202
// ...
)
Don’t use iota for a list of predefined values like FTP server status codes.
const (
Fatal = iota
)
Just assign 0 there. It’s harmless but it’s unnecessary either.


This section will enhance your understanding of iota.




About iota’s behavior on comment and empty lines
type Timezone intconst (
// iota: 0, EST: -5
EST Timezone = -(5 + iota) // On a comment or an empty
// line, iota will not
// increase // iota: 1, CST: -6
CST // iota: 2, MST: -7
MST // iota: 3, MST: -8
PST
)



Multiple iotas in a single line
const (
// Active = 0, Moving = 0,
// Running = 0
Active, Moving, Running = iota, iota, iota // Passive = 1, Stopped = 1,
// Stale = 1
Passive, Stopped, Stale
)
In the same line, all constants will get the same iota values.
const (
// Active = 0, Running = 100
Active, Running = iota, iota + 100 // Passive = 1, Stopped = 101
Passive, Stopped // You can't declare like this.
// The last expression will be
// repeated
CantDeclare // But, you can reset
// the last expression
Reset = iota // You can use any other
// expression even without iota
AnyOther = 10
)


Repeating and canceling expressions
const (
// iota: 0, One: 1 (type: int64)
One int64 = iota + 1 // iota: 1, Two: 2 (type: int64)
// Two will be declared as if:
// Two int64 = iota + 1
Two // iota: 2, Four: 4 (type: int32)
Four int32 = iota + 2 // iota: 3, Five: 5 (type: int32)
// Five will be declared as if:
// Five int32 = iota + 2
Five // (type: int)
Six = 6 // (type: int)
// Seven will be declared as if:
// Seven = 6
Seven
)
The last used expression and type will be repeated.



Counting backward
const (
max = 10
)const (
a = (max - iota) // 10
b // 9
c // 8
)
Go stdlib text scanner also uses this pattern.



Bitwise operations
type Month intconst (
// 1 << 0 ==> 1
January Month = 1 << iota February // 1 << 1 ==> 2
March // 1 << 2 ==> 4
April // 1 << 3 ==> 8
May // 1 << 4 ==> 16
June // ...
July
August
September
October
November
December // Break the iota chain here. // AllMonths will have only
// the assigned month values,
// not the iota's. AllMonths = January | February |
March | April | May | June |
July | August | September |
October | November |
December
)
With the powers of 2, this code creates an all emcompassing constant from the previous constants.


Beware the zero-value
type Activity intconst (
Sleeping = iota
Walking
Running
)func main() {
var activity Activity
// activity initialized to
// its zero-value of int
// which is Sleeping
}
0 is a zero-value for integers. So, you can’t know whether the Activity is initialized or not; Is it really in the Sleeping state?


iota + 1 trick
const (
Sleeping = iota + 1
Walking
Running
)func main() {
var activity Activity
// activity will be zero,
// so it's not initialized activity = Sleeping
// now you know that it's been
// initialized
}
Use “iota + 1” to be sure that the enum type is initialized.




▶︎ In the Greek alphabet, iota is the ninth and the smallest letter (in terms of its visual representation). Pronounced like this. It represents a very small quantity of something.
⟦ In vector math, and in some programming languages, it’s been used to generate an array of consecutive integers as in 1, 2, 3, 4… ⟧
♛ If you’re curious just like me, you can read the implementation of constants, and iota in Go source code. Iota is declared here as const iota = 0
. And, the constant implementation is here, and the behavior of incrementing iota is here.
★ Iota was in Iverson’s book: A Programming Language (APL) from 1962.
★ Iota borrowed from APL by one of the creators of Go, Ken Thompson.
★ A discussion to make iota work with variables in Go 2.

Alright, that’s all for now. Thank you for reading so far.
Let’s stay in touch:
- 📩 Join my newsletter
- 🐦 Follow me on twitter
- 📦 Get my Go repository for free tutorials, examples, and exercises
- 📺 Learn Go with my Go Bootcamp Course
- ❤️ Do you want to help? Please clap and share the article. Let other people also learn from this article.