They don't know about golang stringer.

Published on Oct 26, 2025

#golang enums stringer

They might have told you that Go’s approach to enums is inconvenient, or even that the language lacks support for enums entirely. While it’s true that Go doesn’t have a dedicated enum keyword or support for it like most languages, it offers a robust, idiomatic solution using const, iota, and a custom type.
The real problem isn’t the definition; it’s the readability and maintenance that trip most developers up.


The unreadable enum problem

Consider a standard Go constant block defining the days of the week:


package main

type Day int

const (
  Sunday Day = iota // Sunday will be 0
  Monday            // Monday will be 1
  Tuesday           // Tuesday will be 2
  Wednesday
  Thursday
  Friday
  Saturday
)

func main() {
    d := Tuesday
    fmt.Println(d)
    // Output: 2
}

The output 2, is useless for logging, debugging, or API responses. To fix this, the typical manual workaround is to implement the built-in String() string interface method.

The Tedious Manual Solution

To get a human-readable output, developers are forced to write verbose and repetitive code:


// The manual, verbose, and error-prone approach
func (d Day) String() string {
    switch d {
    case Sunday:
        return "Sunday"
    case Monday:
        return "Monday"
    // ... six more cases
    default:
        return fmt.Sprintf("Day(%d)", d)
    }
}

This works, but it's a huge pain point. Every time you add a new constant, you must manually update the switch statement.

If you forget, your code breaks silently or starts printing incorrect strings.


The Idiomatic Fix: stringer

stringer is a code-generation tool provided under golang.org/x/tools that automatically generates the perfect, efficient String() string method for your constant type.

Define your enum types as follows -

package enums

//go:generate stringer -type AccountType
type AccountType int

const (
	NotValid AccountType = iota
	SuperAdmin
	Admin
	Manager
	Employee
	ServiceOwner = Employee
)

//go:generate stringer -type Status -trimprefix Status
type Status int

const (
	StatusOK                Status = 200
	StatusBadRequest        Status = 400
	StatusInternalServerErr Status = 500
)

Make sure you have installed the tool -
go install golang.org/x/tools/cmd/stringer@latest

On executing go generate ./... it generates following Stringer interface implementation -

// Code generated by "stringer -type Status -trimprefix status"; DO NOT EDIT.

package enums

import "strconv"

func _() {
	// An "invalid array index" compiler error signifies that the constant values have changed.
	// Re-run the stringer command to generate them again.
	var x [1]struct{}
	_ = x[NotValid-0]
	_ = x[SuperAdmin-1]
	_ = x[Admin-2]
	_ = x[Manager-3]
	_ = x[Employee-4]
}

const _AccountType_name = "NotValidSuperAdminAdminManagerEmployee"

var _AccountType_index = [...]uint8{0, 8, 18, 23, 30, 38}

func (i AccountType) String() string {
	if i < 0 || i >= AccountType(len(_AccountType_index)-1) {
		return "AccountType(" + strconv.FormatInt(int64(i), 10) + ")"
	}
	return _AccountType_name[_AccountType_index[i]:_AccountType_index[i+1]]
}

func _() {
	// An "invalid array index" compiler error signifies that the constant values have changed.
	// Re-run the stringer command to generate them again.
	var x [1]struct{}
	_ = x[StatusOK-200]
	_ = x[StatusBadRequest-400]
	_ = x[StatusInternalServerErr-500]
}

const (
	_Status_name_0 = "OK"
	_Status_name_1 = "BadRequest"
	_Status_name_2 = "InternalServerErr"
)

func (i Status) String() string {
	switch {
	case i == 200:
		return _Status_name_0
	case i == 400:
		return _Status_name_1
	case i == 500:
		return _Status_name_2
	default:
		return "Status(" + strconv.FormatInt(int64(i), 10) + ")"
	}
}

Why stringer is the “right way”


  • Automation & Maintainability: You never have to manually update string mappings again. Simply re-run stringer after adding a new constant.
  • Type Safety: It generates code that is tied directly to your custom type, keeping things clean and Go-like.
  • Efficiency: The generated code is highly optimized, which is fast and efficient, even for hundreds of constants.
  • Idiomatic Standard: It's a tool from the official golang.org/x/tools library, making it the accepted standard for readable enums in the Go community.

Go tell them about stringer quietly!

Stop writing redundant, error-prone code by just knowing the toolset provided in depth. Start using stringer to elevate your Go enum usage from a manual chore to an automated, idiomatic standard.

© 2026 Shubham Biswas. All Rights Reserved