They don't know about golang stringer.
Published on Oct 26, 2025
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.