Go lang – iota and constants

In programming languages such as C++ and Java, there is Enum type which is used frequently. In go language, you can use iota to represent an Enum type.

Let’s take a look at a simple example

Example

Let’s say you want to define variables to represent weekdays. In that case, you probably just want to have integer values for a simple comparison. (You really don’t want to use string to represent the value unless you are printing) Let’s take a look at a version that naively represents the weekdays.

const (
	SUNDAY = 0
	MONDAY = 1
	TUESDAY = 2
	WEDNESDAY = 3
	THURSDAY = 4
	FRIDAY = 5
	SATURDAY = 6
)

// output
fmt.Println(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY)

0 1 2 3 4 5 6

Now it will perfectly fine because you can use those variables like others. However, it is very tedious to explicitly type all the values because you really don’t care about those. You just want consecutive integers. Here is where iota comes into play to make life better.

What is iota? It is a built-in constant generator that generates consecutively increasing numbers. Let’s take a look at the usage

const (
	SUNDAY = iota
	MONDAY
	TUESDAY
	WEDNESDAY
	THURSDAY
	FRIDAY
	SATURDAY
)

// output
fmt.Println(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY)

0 1 2 3 4 5 6

With iota, you only need to assign iota once to the place you want to generate. iota always starts from 0 and will increase the number and repeat the same assignment as the previous line. In the example above, SUNDAY will be 0. For MONDAY, iota will repeat itself with the increased number which is 1. It will stop once it reaches the end and the value will be reset to 0 so that it won’t disrupt other constant settings. What happens if you want to use iota from the middle part?

const (
	SUNDAY = -1
	MONDAY = iota
	TUESDAY
	WEDNESDAY
	THURSDAY
	FRIDAY
	SATURDAY
)

// output
fmt.Println(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY)
-1 1 2 3 4 5 6

You just have to explicitly set the value before the iota usage. iota will start from there. Note that iota value starts from 1 instead of 0.
Why is that? It’s because iota starts from the beginning of the constants.

Blank Identifier

You can use a formula to set a custom value using iota. iota always starts from 0 and if you want a different value, you have to use some expression to do that. Let’s say you want to represent different timezones in constants. You only want to represent three timezones in the U.S. – EST, MST, PST – compared to UTC. For example, EST means the eastern standard time that is -5 hours behind UTC. MST means mountain time that is -7 hours behind UTC. PST means the pacific time that is -8 hours behind UTC. Therefore you want to have your constants represent like this.

const (
	EST = -5
	MST = -7
	PST = -8
)

fmt.Println(EST, MST, PST)
-5 -7 -8

But how can you use iota here? There are two issues here. iota will return a non-negative increasing number but you want to have negative numbers here. The second issue is that the values we want are not consecutive. Let’s tackle the issue one by one. How can we have negative numbers using iota? We can use a formula to manipulate the value.

const (
	EST = -(iota + 5)
	MST
	PST
)

fmt.Println(EST, MST, PST)
-5 -6 -7

You can use a typical mathematical expression when using iota because it just returns a number.

Now, there is still an issue here. We want -5, -7, -8 but actually got -5, -6, -7 because iota only returns consecutively increased numbers. What can we do? Remember that iota will always increase the value in every line. But We certainly don’t want to declare any dummy constant just for that. Blank identifier comes to the rescue. Blank identifier in go is to tell the compiler this is unused variable and ignore it. It is ‘_’.

const (
	EST = -(iota + 5)
	_
	MST
	PST
)

fmt.Println(EST, MST, PST)
-5 -7 -8

Now, note that iota will increase by 1 at line 3. We all know that ‘_’ is a dummy and can just ignore. In MST, it will be set to -7 which is the correct value now.

Conclusion

We have briefly taken a look at iota and constants in go lang. It could be pretty convenient when used properly. Happy coding!