DEV Community

Alex Leonhardt
Alex Leonhardt

Posted on

Enums in Go - why and how?

Go doesn't (yet) have enums as such, but it seems common to use constants with iota for this instead.

Passing enums instead of strings to a constructor helps reduce possible bugs; when a constructor accepts a set of possible options for an argument, it's easy to "fat finger" (i.e. misspell) them.

Using custom "enums" helps to prevent this and also documents available options for that argument.

Here's what I found on stackoverflow on the why (above), and here's an example I've implemented.


package main

import (


func main() {
    cfg, err := config.New(config.Env)
    fmt.Printf("%#v %#v\n", cfg, err)
    cfg, err = config.New(config.File)
    fmt.Printf("%#v %#v\n", cfg, err)
    cfg, err = config.New(42)
    fmt.Printf("%#v %#v\n", cfg, err)

we're using the New() constructor function in the config package and pass it the config type to return


package config

import (


// Configurer describes a config provider
type Configurer interface {
    Get(string) string
    Set(string) bool
    Del(string) bool

// T is used to select the type of config to return
type T uint

// Constants for T
const (
    Env T = iota

// New takes a config.T type and returns an Configurer
func New(t T) (Configurer, error) {
    switch t {
    case Env:
        return env.New(), nil
    case File:
        return file.New(), nil
        return nil, errors.New("eh?")

we're specifying T as a uint which we'll use as our custom "enum" to pass to New(), depending on the "type", a different Configurer is being initialised (using its own New() constructor) and then returned


package env

type env struct {
    val1 string
    val2 int
    val3 bool

// New creates a new config
func New() *env {
    return &env{}

func (c *env) Get(v string) string {
    return ""
func (c *env) Set(v string) bool {
    return true
func (c *env) Del(v string) bool {
    return true

finally, New() returns a pointer to an initialised env struct which satisfies the config.Configurer interface by implementing the required methods Get, Set and Del.

Hope this helps anyone, it helped me already just by writing this!

If you have any comments, suggestions, better explanations, please do leave a comment. Always happy to learn new things!

Top comments (2)

andreybronin profile image
Andrey Bronin

Guys from Uber recommends to start enum from 1, zero is default(not initialized) value, in this case, you no need "unknown" value

ineedale profile image
Alex Leonhardt • Edited

Thanks! That's actually a good point, although there are valid cases for starting at 0.

Thinking about it, defaulting to 0 in the example case above is probably actually a valid thing to do.

Nevertheless, thanks for the link and tip! I'll have a read through what Uber does and try to learn from them too.