Enums in Go with iota, named types, and String()

Model a golang enum as a named integer type with const iota values, optional String and fmt.Stringer, validation helpers, and JSON encode or decode via maps or custom MarshalJSON when strings cross APIs.

Published

Updated

Read time 2 min read

Reviewed byDeepak Prasad

Enums in Go with iota, named types, and String()

Go has no enum keyword; a golang enum is usually a named integer type plus const values, often driven by iota. That gives compile-time distinct values, optional String() for logging, and small helpers to validate or parse wire strings. For structured data, pair enums with structs and JSON rules that match your API.

Tested with Go 1.24 on Linux.


Basic iota enum

go
package main

import "fmt"

type Weekday int

const (
	Sunday Weekday = iota
	Monday
	Tuesday
	Wednesday
	Thursday
	Friday
	Saturday
)

func main() {
	fmt.Println(int(Sunday), int(Saturday))
}
Output

You should see 0 and 6.


Names and String()

go
package main

import "fmt"

type Status int

const (
	StatusUnknown Status = iota
	StatusOK
	StatusFailed
)

func (s Status) String() string {
	switch s {
	case StatusOK:
		return "OK"
	case StatusFailed:
		return "FAILED"
	default:
		return "UNKNOWN"
	}
}

func main() {
	var st Status = StatusOK
	fmt.Println(st.String())
}
Output

You should see OK.


Parsing strings (API boundary)

go
package main

import "fmt"

type Tier int

const (
	TierFree Tier = iota
	TierPro
)

func ParseTier(s string) (Tier, bool) {
	switch s {
	case "free":
		return TierFree, true
	case "pro":
		return TierPro, true
	default:
		return TierFree, false
	}
}

func main() {
	fmt.Println(ParseTier("pro"))
}
Output

You should see 1 and true.


Summary

A golang enum is idiomatically a typed const block with iota, sometimes with gaps for stable IDs. Add String(), parse helpers, and JSON mapping at the edges where text meets your domain.


References


Frequently Asked Questions

1. Does Go have an enum keyword?

No. Use typed constants with iota or separate const blocks for disjoint sets.

2. What is iota?

A predeclared counter that starts at zero in each const block and increments for each const specifier, handy for sequential numeric enums.

3. How do I print friendly enum names?

Implement fmt.Stringer on the named type or switch on the value in a helper.

4. How do I accept enums from JSON strings?

Unmarshal into string then map with a switch or map[string]YourType, or implement UnmarshalJSON on the named type.

5. Can I skip iota values?

Yes, use explicit assignments or _ placeholders to leave gaps when you need stable wire values.
Antony Shikubu

Systems Integration Engineer

Highly skilled software developer with expertise in Python, Golang, and AWS cloud services.