如何让Go语言把枚举字段打印成字符串?

eagi6jfj  于 2023-01-06  发布在  Go
关注(0)|答案(5)|浏览(286)

你打印一个枚举,它使用“%v”来实现Stringer,它将打印它的字符串值。如果你在一个结构中声明了相同的枚举,并且使用“%v”来打印该结构,它将打印枚举的数值。有没有办法打印枚举字段的字符串值?
样品(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)
}

图纸:

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

tgabmvqs1#

需要将字段设为exported,即可以将结构声明为

type MyStruct struct {
    Field MyEnum
}

下面是一个包含exportedunexported字段的示例程序

代码

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)
}

输出

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

这里是播放链接:https://play.golang.org/p/7knxM4KbLh

jvlzgdj9

jvlzgdj92#

我将用这个方法对公认的答案进行一些扩展:

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

上面的代码假设枚举值从0开始,这很好地实现了,因为String方法中数组的第一个元素可以直接被枚举值引用。
但是原始问题中的第一个枚举值的值为1。我们可以相应地修改它的方法。

const (
    Foo MyEnum = iota + 1
    Bar
)

func (me MyEnum) String() string {
    return [...]string{"", "Foo", "Bar"}[me]
}

以下是播放链接:https://play.golang.org/p/6pmyVlsAeV2

wlwcrazw

wlwcrazw3#

使用stringer。它是Golang工具链中不可或缺的一部分,专门为此任务而制造。

a14dhokn

a14dhokn4#

你可能想使用godocs中提到的标准枚举器包:https://godoc.org/github.com/alvaroloes/enumer
附言:有一些叉子已经在上面的项目中工作过了。但是对于你的要求,这应该足够了。

txu3uszq

txu3uszq5#

您所要做的就是在定义ENUM的类型上实现String方法

请看此示例

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
}

相关问题