如何使Go打印枚举字段为字符串?

huangapple go评论115阅读模式
英文:

How to make Go print enum fields as string?

问题

你可以通过在结构体中定义一个自定义的 String 方法来打印枚举字段的字符串值。在该方法中,你可以根据枚举的值返回相应的字符串表示。

以下是修改后的示例代码:

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 (s MyStruct) String() string {
	return fmt.Sprintf("{field:%s}", s.field)
}

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
{field:Foo}
&{field:1}
&main.MyStruct{field:1}

现在,当你使用 %v 打印结构体时,它将打印枚举字段的字符串值。

英文:

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}

答案1

得分: 28

你需要将字段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}

这是Play链接:https://play.golang.org/p/7knxM4KbLh

英文:

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

答案2

得分: 16

我将使用以下方法对接受的答案进行扩展:

type MyEnum int

const (
	Foo MyEnum = iota
	Bar
)

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

// ...

fmt.Println(Foo, Bar)  // 输出:Foo Bar

上述代码假设枚举值从0开始,这很好,因为在String方法中数组的第一个元素可以直接通过枚举值引用。

但是原始问题中的第一个枚举值的值为1。我们可以相应地修改该方法。

const (
	Foo MyEnum = iota + 1
	Bar
)

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

这是playlink链接:https://play.golang.org/p/6pmyVlsAeV2

英文:

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

答案3

得分: 9

使用stringer。它是Golang工具链的一个重要组成部分,专门用于这个任务。

英文:

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

答案4

得分: 0

你可能想使用一个标准的枚举器包,如godocs中提到的:https://godoc.org/github.com/alvaroloes/enumer

附注:有一些分支已经在上述项目上进行了工作。但对于你的需求,这应该足够了。

英文:

You might want to use a standard enumerator package as mentioned in godocs: https://godoc.org/github.com/alvaroloes/enumer

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

答案5

得分: 0

你只需要在定义ENUM的类型上实现String方法即可。

看一下这个例子

package main

import "fmt"

// Day是表示星期几的类型
// 这里将是unit8的别名
type Day uint8

// 星期几的枚举
const (
    InvalidDay Day = iota // 无效的日期为0
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
    Sunday
)

// String方法负责将枚举值转换为字符串并打印出来
// 当你调用fmt.Println()或其他格式化函数时,它会被默认调用
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("我最喜欢的一天是:%v\n", Monday) // 我最喜欢的一天是:Monday
}
英文:

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
}

huangapple
  • 本文由 发表于 2017年1月5日 16:43:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/41480543.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定