[Golang] Enum and String Representation


Recently I use Go enums [2] [4] to represent the type of webpage:

package lib

// Type of the webpage, determined according to path of URL
type PageType int

const (
      RootPage PageType = iota
      AboutPage
      WordPage
      NoSuchPage
)

// Determine the type of the webpage according to path of URL.
func DeterminePageType(urlpath string) PageType
      // implementation ignored
}

After reading the discussion of reddit, I found that I can use go:generate and stringer command to indirectly get the string representation of enumerated type (i.e., enum name).

First install stringer command:

$ go get -u golang.org/x/tools/cmd/stringer

Give hint to go generate command in the code by adding the comment:

//go:generate stringer -type=PageType

So the code will become:

package lib

// Type of the webpage, determined according to path of URL
//go:generate stringer -type=PageType
type PageType int

const (
      RootPage PageType = iota
      AboutPage
      WordPage
      NoSuchPage
)

// Determine the type of the webpage according to path of URL.
func DeterminePageType(urlpath string) PageType
      // implementation ignored
}

Run go generate command in the directory of the source code:

$ go generate

A file named pagetype_string.go will be generated automatically. The content of pagetype_string.go is:

// Code generated by "stringer -type=PageType"; DO NOT EDIT.

package lib

import "fmt"

const _PageType_name = "RootPageAboutPageWordPageNoSuchPage"

var _PageType_index = [...]uint8{0, 8, 17, 25, 35}

func (i PageType) String() string {
      if i < 0 || i >= PageType(len(_PageType_index)-1) {
              return fmt.Sprintf("PageType(%d)", i)
      }
      return _PageType_name[_PageType_index[i]:_PageType_index[i+1]]
}

An example usage of string representation of enum is to print the enum name if something goes wrong in the testing code:

package lib

import "testing"

func TestDeterminePageType(t *testing.T) {
      if pt := DeterminePageType("/"); pt != RootPage {
              t.Error("wrong type: ", pt.String())
      }
}

Tested on: Go 1.8, Ubuntu Linux 16.10


References:

[1]
[2]
[3]
[4]Constants - Effective Go - The Go Programming Language
[5]
[6]Generating code - The Go Blog
[7]