How to make Go print enum fields as string?

You print an enum that implements Stringer using "%v", it will print its string value. If you declare the same enum inside a struct and print the struct using "%v", it will print enum's numeric value. Is there a way to print the string value of a enum field?

Sample ():

package main
import ( "fmt"
)
type MyEnum int
const ( Foo MyEnum = 1 Bar MyEnum = 2
)
func (e MyEnum) String() string { switch e { case Foo: return "Foo" case Bar: return "Bar" default: return fmt.Sprintf("%d", int(e)) }
}
type MyStruct struct { field MyEnum
}
func main() { info := &MyStruct{ field: MyEnum(1), } fmt.Printf("%v\n", MyEnum(1)) fmt.Printf("%v\n", info) fmt.Printf("%+v\n", info) fmt.Printf("%#v\n", info)
}

Prints:

Foo
&{1}
&{field:1}
&main.MyStruct{field:1}
4

6 Answers

You need to make the field exported,ie you may declare the struct as

type MyStruct struct { Field MyEnum
}

Here is a sample program with exported and unexported fields

Code

package main
import ( "fmt"
)
type MyEnum int
const ( Foo MyEnum = 1 Bar MyEnum = 2
)
func (e MyEnum) String() string { switch e { case Foo: return "Foo" case Bar: return "Bar" default: return fmt.Sprintf("%d", int(e)) }
}
type MyStruct struct { Field1 MyEnum field2 MyEnum
}
func main() { info := &MyStruct{ Field1: MyEnum(1), field2: MyEnum(2), } fmt.Printf("%v\n", MyEnum(1)) fmt.Printf("%v\n", info) fmt.Printf("%+v\n", info) fmt.Printf("%#v\n", info)
}

Output

Foo
&{Foo 2}
&{Field1:Foo field2:2}
&main.MyStruct{Field1:1, field2:2}

Here is play link :

1

I am going to expand on the accepted answer a little with this method:

type MyEnum int
const ( Foo MyEnum = iota Bar
)
func (me MyEnum) String() string { return [...]string{"Foo", "Bar"}[me]
}
// ...
fmt.Println(Foo, Bar) // Prints: Foo Bar

The above code assumes that the enum values starts from 0, which works out nicely because the first element in the array in the method String can be referenced by the enum value directly.

But the first enum value in the original question has a value of 1. We can modify it the method accordingly.

const ( Foo MyEnum = iota + 1 Bar
)
func (me MyEnum) String() string { return [...]string{"", "Foo", "Bar"}[me]
}

Here's the playlink:

3

Use stringer. It is an integral part of the Golang tool chain and is made specifically for this task.

You might want to use a standard enumerator package as mentioned in godocs:

PS: There are some forks which have worked on the above project. But for your requirement, this should be sufficient.

All you have to do is to implement String method on the type that defines the ENUM

take a look at this example

package main
import "fmt"
// Day is the type that represents the day
// and here will be an alias of unit8
type Day uint8
// Enum of week days
const ( InvalidDay Day = iota // invalid day will be 0 Monday Tuesday Wednesday Thursday Friday Saturday Sunday
)
// String method is responsible for how enum values
// will be converted to string and printed
// it will be called by default when you call fmt.Println()
// or other formatting functions
func (d Day) String() string { switch d { case Monday: return "Monday" case Tuesday: return "Tuesday" case Wednesday: return "Wednesday" case Thursday: return "Thursday" case Friday: return "Friday" case Saturday: return "Saturday" case Sunday: return "Sunday" default: return "Invalid Week Day" }
}
func main() { fmt.Printf("My favourite day is: %v\n", Monday) // My favourite day is: Monday
}

Not an exact answer to the question. But there are no in-built functions for enums in Go. I use the following method which is less verbose. It may or may not work for all. In my enums package, I create constants with the enum name prefixed. Like AuthTypeGoogle, AuthTypeApple. These constants are string type and PascalCase so that it is exported automatically.

package enums
const ( AuthTypeGoogle = "Google" AuthTypeApple = "Apple" AuthTypePhone = "Phone"
)
const ( UserTypePerson = "Person" UserTypeHr = "Hr" UserTypeEmployee = "Employee"
)

Now I import the enum package and use it like if(userTypeValue == enums.UserTypePerson) and that's it. What I'm concerned about is done.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like