ProgrammingBackend Developer

What are the features of working with constants of type iota in Go and how to properly use multiple related constants?

Pass interviews with Hintsage AI assistant

Answer.

Background:

Constants in Go are an integral part of the language. The identifier iota is used for grouped constants with auto-numbers, introduced in the earliest versions of Go to simplify the declaration of logically related values.

Issue:

Many developers make mistakes when working with iota, misinterpreting how and where it increments and how it applies in complex declaration patterns. This leads to incorrect values even for simple enum-like structures.

Solution:

iota allows for declaring sequential constants and conveniently assembling bit flags. It starts at zero in each new constant group. Each new const block or new line in the block increments the value of iota.

Code example:

// Example of a flag mask and enum with iota const ( _ = iota // skip zero FlagRead // 1 FlagWrite // 2 FlagExecute // 3 ) const ( ( // bit flags FlagA = 1 << iota // 1 << 0 = 1 FlagB // 1 << 1 = 2 FlagC // 1 << 2 = 4 ) )

Key features:

  • iota resets to zero in the block, starting again with each const group.
  • Combined and bit values can be set via iota.
  • When skipping a line, the expression duplicates automatically while iota increments.

Trick questions.

Can iota increment outside of a const block or when declaring a constant not in a group?

No, iota works only within a const group. In a single declaration, it is always 0.

const A = iota // 0 const B = iota // 0 (new block)

What happens if not all values in the group use iota?

Only those explicitly specified will receive a new value; the rest inherit the expression from the previous line.

const ( A = iota // 0 B // 1 C = 10 // 10 D // 10 (not iota, but repeating the expression from C) )

How to declare bit masks using iota?

Bit masks are implemented through shifts: 1 << iota.

const ( F1 = 1 << iota // 1 F2 // 2 F3 // 4 )

Common mistakes and anti-patterns

  • Forgetting to reset iota between const groups.
  • Using iota for constants without auto-numbering, which reduces readability.
  • Incorrectly mixing regular values and values via iota.

Real-life example

Negative case

An engineer declares bit flags in different groups, thinking that iota will continue counting:

const ( FlagA = 1 << iota // 1 FlagB // 2 ) const ( FlagC = 1 << iota // 1 – not 3 as expected! )

Pros:

  • Simplicity of declaration

Cons:

  • Flags overlap in value, causing bugs during bitwise operations.

Positive case

All related constants are combined into one group:

const ( FlagA = 1 << iota FlagB FlagC )

Pros:

  • Values are unique and do not overlap, easy to change order/add new ones.

Cons:

  • All values must be logically related