How to make Go print enum fields as string?
Solution 1
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 : https://play.golang.org/p/7knxM4KbLh
Solution 2
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: https://play.golang.org/p/6pmyVlsAeV2
Solution 3
Use stringer
. It is an integral part of the Golang tool chain and is made specifically for this task.
Related videos on Youtube
![Igor Gatis](https://i.stack.imgur.com/s4CXR.jpg?s=256&g=1)
Igor Gatis
Updated on July 14, 2021Comments
-
Igor Gatis almost 3 years
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 (https://play.golang.org/p/AP_tzzAZMI):
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}
-
GarMan over 7 yearsThis is a dup of stackoverflow.com/questions/27187132/… , there is no way to get the name of the enum in go, you need to create a lut with a tool like stringify
-
icza over 7 years@GarMan The question is not about how to write or generate the
String()
method, it's about he already added theString()
, yet thefmt
package doesn't call it when an instance of a wrapperstruct
(or a pointer to it) is printed. -
Sarath Sadasivan Pillai over 7 years@Gatis you need to export the field. I have added the answer with a sample.Please check and if it solves your problem accept it
-
GarMan over 7 yearsMy bad, I misread, @Sarathsp's answer is correct please accept it.
-
-
Sarath Sadasivan Pillai over 7 yearsif you want '%#v' also to show the string you need to implement 'fmt.GoStringer'
-
giles about 3 yearsCan you explain the ellipsis used here?
[...] string { "a", "b", "c" } [n]
appears to give me the same result as without the ellipsis[] string { "a", "b", "c" } [n]
So I am not sure what purpose the ellipsis is serving. -
Cybersam about 3 yearsYes. Both
[...] string { "a", "b", "c" } [n]
and[] string { "a", "b", "c" } [n]
give the same result. The difference is the former creates an array and the latter a slice. This declares a slice:a := string { "a", "b", "c" }
. This declares an array of 2:b := [3]string{ "a", "b", "c" }
. This is the same as the previous except you let Go compiler to do the counting of elements for you:b := [...]string{ "a", "b", "c" }
. Reference: blog.golang.org/slices-intro -
Rishabh Bhatnagar about 3 yearsThis way, you'll be creating a slice on every call to the function. Either define this mapping as a global object or use a switch. Else, the memory's gonna blow if there are a large number of threads trying to use the enum object's string.