🧐 iota in Go - how to use?

introduction iota const

The iota keyword within a constant declaration represents successive untyped integers starting from zero. When declaring constants, it often does not matter what their specific values are, but that they are distinct from each other, so instead of declaring constants in the form:

const (
	Strawberry = "strawberry"
	Blueberry  = "blueberry"
	Raspberry  = "raspberry"
)

we can declare them as integers:

const (
	Strawberry = 1
	Blueberry  = 2
	Raspberry  = 3
)

and this declaration can be further simplified by the iota keyword:

const (
	Strawberry = iota + 1
	Blueberry // in Go, omitting the value of constant 
        // within the constants list declaration is equivalent 
        // to repeating the previous line value
	Raspberry
)

The iota keyword starts a counter that increments for each line of the const declaration. Because its initial value is zero, in the example above, we declare the first constant as iota + 1. As a result, we receive 1 for Strawberry, 2 for Blueberry, and 3 for Raspberry.

Skip iota value

If you want to skip an integer value in const declaration with iota, you can use the blank identifier _:

package main

import "fmt"

const (
	Strawberry = iota + 1
	Blueberry
	Raspberry
	_
	Apple
)

func main() {
	fmt.Println(Strawberry, Blueberry, Raspberry, Apple)
}

Advanced example

In addition to simply incrementing values, the iota keyword can also be used to compute more complex expressions. The example below, from Effective Go, shows the combination of the iota keyword, bitwise shift, and a custom type declaration with a String() method that formats the data differently depending on the value.

package main

import "fmt"

type ByteSize float64

const (
	KB ByteSize = 1 << (10 * (iota + 1))
	MB
	GB
)

func (b ByteSize) String() string {
	switch {
	case b >= GB:
		return fmt.Sprintf("%.2fGB", b/GB)
	case b >= MB:
		return fmt.Sprintf("%.2fMB", b/MB)
	case b >= KB:
		return fmt.Sprintf("%.2fKB", b/KB)
	}
	return fmt.Sprintf("%.2fB", b)
}

func main() {
	fmt.Println(1001*KB, 2.5*MB, 3.5*GB)
	fmt.Println(ByteSize(121000000))
}

Output:

1001.00KB 2.50MB 3.50GB
115.39MB

🖐️ Declare enum in Go

Learn how to declare and use enums
introduction enum iota const

🖨️ Convert string to []byte or []byte to string in Go

Learn the difference between a string and a byte slice
introduction strings slice

🧠 Print the memory address of a variable in Go

Learn how to find and print the address of a variable or pointer
introduction pointer slice