在Go语言中,表示枚举的惯用方式是什么?

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

What is an idiomatic way of representing enums in Go?

问题

我正在尝试表示一个简化的染色体,它由N个碱基组成,每个碱基只能是{A, C, T, G}中的一个。

我想用一个枚举来形式化这些约束条件,但我想知道在Go语言中模拟枚举的最常用方式是什么。

英文:

I'm trying to represent a simplified chromosome, which consists of N bases, each of which can only be one of {A, C, T, G}.

I'd like to formalize the constraints with an enum, but I'm wondering what the most idiomatic way of emulating an enum is in Go.

答案1

得分: 885

引用自语言规范:Iota

> 在常量声明中,预声明的标识符iota表示连续的无类型整数常量。每当源代码中出现保留字const时,它将被重置为0,并在每个ConstSpec之后递增。它可以用于构建一组相关的常量:

const (  // iota被重置为0
        c0 = iota  // c0 == 0
        c1 = iota  // c1 == 1
        c2 = iota  // c2 == 2
)

const (
        a = 1 << iota  // a == 1(iota已被重置)
        b = 1 << iota  // b == 2
        c = 1 << iota  // c == 4
)

const (
        u         = iota * 42  // u == 0     (无类型整数常量)
        v float64 = iota * 42  // v == 42.0  (float64常量)
        w         = iota * 42  // w == 84    (无类型整数常量)
)

const x = iota  // x == 0(iota已被重置)
const y = iota  // y == 0(iota已被重置)

> 在ExpressionList中,每个iota的值相同,因为它仅在每个ConstSpec之后递增:

const (
        bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0
        bit1, mask1                           // bit1 == 2, mask1 == 1
        _, _                                  // 跳过iota == 2
        bit3, mask3                           // bit3 == 8, mask3 == 7
)

> 最后一个示例利用了最后一个非空表达式列表的隐式重复。


因此,你的代码可以是这样的:

const (
        A = iota
        C
        T
        G
)

或者

type Base int

const (
        A Base = iota
        C
        T
        G
)

如果你希望bases是一个与int不同的类型。

英文:

Quoting from the language specs:Iota

> Within a constant declaration, the predeclared identifier iota represents successive untyped integer constants. It is reset to 0 whenever the reserved word const appears in the source and increments after each ConstSpec. It can be used to construct a set of related constants:

const (  // iota is reset to 0
        c0 = iota  // c0 == 0
        c1 = iota  // c1 == 1
        c2 = iota  // c2 == 2
)

const (
        a = 1 << iota  // a == 1 (iota has been reset)
        b = 1 << iota  // b == 2
        c = 1 << iota  // c == 4
)

const (
        u         = iota * 42  // u == 0     (untyped integer constant)
        v float64 = iota * 42  // v == 42.0  (float64 constant)
        w         = iota * 42  // w == 84    (untyped integer constant)
)

const x = iota  // x == 0 (iota has been reset)
const y = iota  // y == 0 (iota has been reset)

> Within an ExpressionList, the value of each iota is the same because it is only incremented after each ConstSpec:

const (
        bit0, mask0 = 1 << iota, 1<<iota - 1  // bit0 == 1, mask0 == 0
        bit1, mask1                           // bit1 == 2, mask1 == 1
        _, _                                  // skips iota == 2
        bit3, mask3                           // bit3 == 8, mask3 == 7
)

> This last example exploits the implicit repetition of the last non-empty expression list.


So your code might be like

const (
        A = iota
        C
        T
        G
)

or

type Base int

const (
        A Base = iota
        C
        T
        G
)

if you want bases to be a separate type from int.

答案2

得分: 117

参考jnml的答案,您可以通过根本不导出Base类型(即将其写为小写)来防止创建Base类型的新实例。如果需要,您可以创建一个可导出的接口,该接口具有返回基本类型的方法。这个接口可以在外部处理Bases的函数中使用,例如:

package a

type base int

const (
    A base = iota
    C
    T
    G
)


type Baser interface {
    Base() base
}

// 每个base都必须满足Baser接口
func(b base) Base() base {
    return b
}


func(b base) OtherMethod()  {
}

package main

import "a"

// 外部函数通过a.Baser处理a.base
// 由于a.base没有被导出,因此只能使用在a包内创建的导出的bases,如a.A、a.C、a.T和a.G
func HandleBasers(b a.Baser) {
    base := b.Base()
    base.OtherMethod()
}


// 外部函数根据条件返回a.A或a.C
func AorC(condition bool) a.Baser {
    if condition {
       return a.A
    }
    return a.C
}

在main包中,a.Baser现在实际上就像一个枚举类型。只有在a包内部才能定义新的实例。

英文:

Referring to the answer of jnml, you could prevent new instances of Base type by not exporting the Base type at all (i.e. write it lowercase). If needed, you may make an exportable interface that has a method that returns a base type. This interface could be used in functions from the outside that deal with Bases, i.e.

package a

type base int

const (
    A base = iota
    C
    T
    G
)


type Baser interface {
    Base() base
}

// every base must fulfill the Baser interface
func(b base) Base() base {
    return b
}


func(b base) OtherMethod()  {
}

package main

import "a"

// func from the outside that handles a.base via a.Baser
// since a.base is not exported, only exported bases that are created within package a may be used, like a.A, a.C, a.T. and a.G
func HandleBasers(b a.Baser) {
    base := b.Base()
    base.OtherMethod()
}


// func from the outside that returns a.A or a.C, depending of condition
func AorC(condition bool) a.Baser {
    if condition {
       return a.A
    }
    return a.C
}

Inside the main package a.Baser is effectively like an enum now.
Only inside the a package you may define new instances.

答案3

得分: 64

你可以这样做:

type MessageType int32

const (
	TEXT   MessageType = 0
	BINARY MessageType = 1
)

使用这段代码,编译器应该检查枚举的类型。

英文:

You can make it so:

type MessageType int32

const (
	TEXT   MessageType = 0
	BINARY MessageType = 1
)

With this code compiler should check type of enum

答案4

得分: 61

这是使用constiota的示例,它们是在Go中表示原始枚举的最常见方式。但是,如果你想要创建一个更完整的枚举,类似于Java或Python中的类型,该怎么办呢?

在Python中,创建一个类似字符串枚举的对象的非常简单的方法是:

package main

import (
	"fmt"
)

var Colors = newColorRegistry()

func newColorRegistry() *colorRegistry {
	return &colorRegistry{
		Red:   "red",
		Green: "green",
		Blue:  "blue",
	}
}

type colorRegistry struct {
	Red   string
	Green string
	Blue  string
}

func main() {
	fmt.Println(Colors.Red)
}

假设你还想要一些实用方法,比如Colors.List()Colors.Parse("red")。并且你的颜色更复杂,需要使用结构体。那么你可以做一些类似这样的事情:

package main

import (
	"errors"
	"fmt"
)

var Colors = newColorRegistry()

type Color struct {
	StringRepresentation string
	Hex                  string
}

func (c *Color) String() string {
	return c.StringRepresentation
}

func newColorRegistry() *colorRegistry {

	red := &Color{"red", "F00"}
	green := &Color{"green", "0F0"}
	blue := &Color{"blue", "00F"}

	return &colorRegistry{
		Red:    red,
		Green:  green,
		Blue:   blue,
		colors: []*Color{red, green, blue},
	}
}

type colorRegistry struct {
	Red   *Color
	Green *Color
	Blue  *Color

	colors []*Color
}

func (c *colorRegistry) List() []*Color {
	return c.colors
}

func (c *colorRegistry) Parse(s string) (*Color, error) {
	for _, color := range c.List() {
		if color.String() == s {
			return color, nil
		}
	}
	return nil, errors.New("couldn't find it")
}

func main() {
	fmt.Printf("%s\n", Colors.List())
}

到这一点,确实可以工作,但你可能不喜欢如何重复定义颜色。如果你想要消除这一点,你可以在结构体上使用标签,并使用一些反射技巧来设置它,但希望这足以满足大多数人的需求。

英文:

It's true that the above examples of using const and iota are the most idiomatic ways of representing primitive enums in Go. But what if you're looking for a way to create a more fully-featured enum similar to the type you'd see in another language like Java or Python?

A very simple way to create an object that starts to look and feel like a string enum in Python would be:

package main

import (
	"fmt"
)

var Colors = newColorRegistry()

func newColorRegistry() *colorRegistry {
	return &colorRegistry{
		Red:   "red",
		Green: "green",
		Blue:  "blue",
	}
}

type colorRegistry struct {
	Red   string
	Green string
	Blue  string
}

func main() {
	fmt.Println(Colors.Red)
}

Suppose you also wanted some utility methods, like Colors.List(), and Colors.Parse("red"). And your colors were more complex and needed to be a struct. Then you might do something a bit like this:

package main

import (
	"errors"
	"fmt"
)

var Colors = newColorRegistry()

type Color struct {
	StringRepresentation string
	Hex                  string
}

func (c *Color) String() string {
	return c.StringRepresentation
}

func newColorRegistry() *colorRegistry {

	red := &Color{"red", "F00"}
	green := &Color{"green", "0F0"}
	blue := &Color{"blue", "00F"}

	return &colorRegistry{
		Red:    red,
		Green:  green,
		Blue:   blue,
		colors: []*Color{red, green, blue},
	}
}

type colorRegistry struct {
	Red   *Color
	Green *Color
	Blue  *Color

	colors []*Color
}

func (c *colorRegistry) List() []*Color {
	return c.colors
}

func (c *colorRegistry) Parse(s string) (*Color, error) {
	for _, color := range c.List() {
		if color.String() == s {
			return color, nil
		}
	}
	return nil, errors.New("couldn't find it")
}

func main() {
	fmt.Printf("%s\n", Colors.List())
}

At that point, sure it works, but you might not like how you have to repetitively define colors. If at this point you'd like to eliminate that, you could use tags on your struct and do some fancy reflecting to set it up, but hopefully this is enough to cover most people.

答案5

得分: 41

有一种方法是使用结构体命名空间。

好处是所有的枚举变量都在一个特定的命名空间下,以避免污染。
问题是我们只能使用var而不是const

type OrderStatusType string

var OrderStatus = struct {
	APPROVED         OrderStatusType
	APPROVAL_PENDING OrderStatusType
	REJECTED         OrderStatusType
	REVISION_PENDING OrderStatusType
}{
	APPROVED:         "approved",
	APPROVAL_PENDING: "approval pending",
	REJECTED:         "rejected",
	REVISION_PENDING: "revision pending",
}
英文:

There is a way with struct namespace.

The benefit is all enum variables are under a specific namespace to avoid pollution.
The issue is that we could only use var not const

type OrderStatusType string

var OrderStatus = struct {
	APPROVED         OrderStatusType
	APPROVAL_PENDING OrderStatusType
	REJECTED         OrderStatusType
	REVISION_PENDING OrderStatusType
}{
	APPROVED:         "approved",
	APPROVAL_PENDING: "approval pending",
	REJECTED:         "rejected",
	REVISION_PENDING: "revision pending",
}

答案6

得分: 22

从Go 1.4版本开始,引入了go generate工具,以及与之一起使用的stringer命令,使得您的枚举类型易于调试和打印。

英文:

As of Go 1.4, the go generate tool has been introduced together with the stringer command that makes your enum easily debuggable and printable.

答案7

得分: 20

对于这样的用例,使用字符串常量可能很有用,因为它可以被编组成JSON字符串。在下面的示例中,[]Base{A,C,G,T}将被编组成["adenine","cytosine","guanine","thymine"]

type Base string

const (
	A Base = "adenine"
	C      = "cytosine"
	G      = "guanine"
	T      = "thymine"
)

当使用iota时,值将被编组成整数。在下面的示例中,[]Base{A,C,G,T}将被编组成[0,1,2,3]

type Base int

const (
    A Base = iota
    C
    G
    T
)

这里有一个比较两种方法的示例:

https://play.golang.org/p/VvkcWvv-Tvj

英文:

For a use case like this, it may be useful to use a string constant so it can be marshaled into a JSON string. In the following example, []Base{A,C,G,T} would get marshaled to ["adenine","cytosine","guanine","thymine"].

type Base string

const (
	A Base = "adenine"
	C      = "cytosine"
	G      = "guanine"
	T      = "thymine"
)

When using iota, the values get marshaled into integers. In the following example, []Base{A,C,G,T} would get marshaled to [0,1,2,3].

type Base int

const (
    A Base = iota
    C
    G
    T
)

Here's an example comparing both approaches:

https://play.golang.org/p/VvkcWvv-Tvj

答案8

得分: 19

我确定我们在这里有很多好答案。但是,我刚想到了添加我使用过的枚举类型的方法。

package main

import "fmt"

type Enum interface {
    name() string
    ordinal() int
    values() *[]string
}

type GenderType uint

const (
    MALE = iota
    FEMALE
)

var genderTypeStrings = []string{
    "MALE",
    "FEMALE",
}

func (gt GenderType) name() string {
    return genderTypeStrings[gt]
}

func (gt GenderType) ordinal() int {
    return int(gt)
}

func (gt GenderType) values() *[]string {
    return &genderTypeStrings
}

func main() {
    var ds GenderType = MALE
    fmt.Printf("The Gender is %s\n", ds.name())
}

这是到目前为止我们可以在Go中创建枚举类型并使用的一种惯用方法。

编辑:

添加使用常量进行枚举的另一种方法

package main

import (
    "fmt"
)

const (
    // UNSPECIFIED不记录任何内容
    UNSPECIFIED Level = iota // 0 :
    // TRACE记录所有内容
    TRACE // 1
    // INFO记录信息、警告和错误
    INFO // 2
    // WARNING记录警告和错误
    WARNING // 3
    // ERROR只记录错误
    ERROR // 4
)

// Level保存日志级别。
type Level int

func SetLogLevel(level Level) {
    switch level {
    case TRACE:
        fmt.Println("trace")
        return

    case INFO:
        fmt.Println("info")
        return

    case WARNING:
        fmt.Println("warning")
        return
    case ERROR:
        fmt.Println("error")
        return

    default:
        fmt.Println("default")
        return

    }
}

func main() {

    SetLogLevel(INFO)

}
英文:

I am sure we have a lot of good answers here. But, I just thought of adding the way I have used enumerated types

package main

import "fmt"

type Enum interface {
	name() string
	ordinal() int
	values() *[]string
}

type GenderType uint

const (
	MALE = iota
	FEMALE
)

var genderTypeStrings = []string{
	"MALE",
	"FEMALE",
}

func (gt GenderType) name() string {
	return genderTypeStrings[gt]
}

func (gt GenderType) ordinal() int {
	return int(gt)
}

func (gt GenderType) values() *[]string {
	return &genderTypeStrings
}

func main() {
	var ds GenderType = MALE
	fmt.Printf("The Gender is %s\n", ds.name())
}

This is by far one of the idiomatic ways we could create Enumerated types and use in Go.

Edit:

Adding another way of using constants to enumerate

package main

import (
	"fmt"
)

const (
	// UNSPECIFIED logs nothing
	UNSPECIFIED Level = iota // 0 :
	// TRACE logs everything
	TRACE // 1
	// INFO logs Info, Warnings and Errors
	INFO // 2
	// WARNING logs Warning and Errors
	WARNING // 3
	// ERROR just logs Errors
	ERROR // 4
)

// Level holds the log level.
type Level int

func SetLogLevel(level Level) {
	switch level {
	case TRACE:
		fmt.Println("trace")
		return

	case INFO:
		fmt.Println("info")
		return

	case WARNING:
		fmt.Println("warning")
		return
	case ERROR:
		fmt.Println("error")
		return

	default:
		fmt.Println("default")
		return

	}
}

func main() {

	SetLogLevel(INFO)

}

答案9

得分: 9

这是一个例子,当有许多枚举时,它将证明有用。它使用了Golang中的结构,并借鉴了面向对象的原则,将它们整合在一个整洁的包中。当添加或删除新的枚举时,底层代码不会改变。过程如下:

  • 枚举项定义一个枚举结构:EnumItem。它有一个整数和字符串类型。
  • 枚举定义为枚举项的列表:Enum
  • 为枚举构建方法。已包含了一些方法:
    • enum.Name(index int):返回给定索引的名称。
    • enum.Index(name string):返回给定名称的索引。
    • enum.Last():返回最后一个枚举的索引和名称。
  • 添加你的枚举定义。

以下是一些代码:

type EnumItem struct {
    index int
    name  string
}

type Enum struct {
    items []EnumItem
}

func (enum Enum) Name(findIndex int) string {
    for _, item := range enum.items {
        if item.index == findIndex {
            return item.name
        }
    }
    return "未找到ID"
}

func (enum Enum) Index(findName string) int {
    for idx, item := range enum.items {
        if findName == item.name {
            return idx
        }
    }
    return -1
}

func (enum Enum) Last() (int, string) {
    n := len(enum.items)
    return n - 1, enum.items[n-1].name
}

var AgentTypes = Enum{[]EnumItem{{0, "StaffMember"}, {1, "Organization"}, {1, "Automated"}}}
var AccountTypes = Enum{[]EnumItem{{0, "Basic"}, {1, "Advanced"}}}
var FlagTypes = Enum{[]EnumItem{{0, "Custom"}, {1, "System"}}}
英文:

Here is an example that will prove useful when there are many enumerations. It uses structures in Golang, and draws upon Object Oriented Principles to tie them all together in a neat little bundle. None of the underlying code will change when a new enumeration is added or deleted. The process is:

  • Define an enumeration structure for enumeration items: EnumItem. It has an integer and string type.
  • Define the enumeration as a list of enumeration items: Enum
  • Build methods for the enumeration. A few have been included:
    • enum.Name(index int): returns the name for the given index.
    • enum.Index(name string): returns the name for the given index.
    • enum.Last(): returns the index and name of the last enumeration
  • Add your enumeration definitions.

Here is some code:

type EnumItem struct {
    index int
    name  string
}

type Enum struct {
    items []EnumItem
}

func (enum Enum) Name(findIndex int) string {
    for _, item := range enum.items {
        if item.index == findIndex {
            return item.name
        }
    }
    return "ID not found"
}

func (enum Enum) Index(findName string) int {
    for idx, item := range enum.items {
        if findName == item.name {
            return idx
        }
    }
    return -1
}

func (enum Enum) Last() (int, string) {
    n := len(enum.items)
    return n - 1, enum.items[n-1].name
}

var AgentTypes = Enum{[]EnumItem{{0, "StaffMember"}, {1, "Organization"}, {1, "Automated"}}}
var AccountTypes = Enum{[]EnumItem{{0, "Basic"}, {1, "Advanced"}}}
var FlagTypes = Enum{[]EnumItem{{0, "Custom"}, {1, "System"}}}

答案10

得分: 6

重构了https://stackoverflow.com/a/17989915/863651以使其更易读:

package SampleEnum

type EFoo int

const (
    A EFoo = iota
    C
    T
    G
)

type IEFoo interface {
    Get() EFoo
}

func(e EFoo) Get() EFoo { // 每个EFoo都必须满足IEFoo接口
    return e
}

func(e EFoo) otherMethod()  { // "private"
    //一些逻辑
}
英文:

Refactored https://stackoverflow.com/a/17989915/863651 to make it a bit more readable:

package SampleEnum

type EFoo int

const (
	A EFoo = iota
	C
	T
	G
)

type IEFoo interface {
	Get() EFoo
}

func(e EFoo) Get() EFoo { // every EFoo must fulfill the IEFoo interface
	return e
}

func(e EFoo) otherMethod()  { // "private"
	//some logic
}

答案11

得分: 4

这是在golang中实现枚举的安全方式:

package main

import (
	"fmt"
)

const (
	MALE   = _gender(1)
	FEMALE = _gender(2)
	RED    = _color("RED")
	GREEN  = _color("GREEN")
	BLUE   = _color("BLUE")
)

type Gender interface {
	_isGender()
	Value() int
}

type _gender int

func (_gender) _isGender() {}

func (_g _gender) Value() int {
	return int(_g)
}

type Color interface {
	_isColor()
	Value() string
}

type _color string

func (_color) _isColor() {}

func (_c _color) Value() string {
	return string(_c)
}

func main() {
	genders := []Gender{MALE, FEMALE}
	colors := []Color{RED, GREEN, BLUE}
	fmt.Println("Colors =", colors)
	fmt.Println("Genders =", genders)
}

输出结果:

Colors = [RED GREEN BLUE]
Genders = [1 2]
英文:

This is a safe way to implement enum in golang:

package main

import (
	"fmt"
)

const (
	MALE   = _gender(1)
	FEMALE = _gender(2)
	RED    = _color("RED")
	GREEN  = _color("GREEN")
	BLUE   = _color("BLUE")
)

type Gender interface {
	_isGender()
	Value() int
}

type _gender int

func (_gender) _isGender() {}

func (_g _gender) Value() int {
	return int(_g)
}

type Color interface {
	_isColor()
	Value() string
}

type _color string

func (_color) _isColor() {}

func (_c _color) Value() string {
	return string(_c)
}

func main() {
	genders := []Gender{MALE, FEMALE}
	colors := []Color{RED, GREEN, BLUE}
	fmt.Println("Colors =", colors)
	fmt.Println("Genders =", genders)
}

The output:

Colors = [RED GREEN BLUE]
Genders = [1 2]

答案12

得分: 4

此外,这是一种在一个字节中存储不同角色的相当有效的方法,其中第一个值设置为1,通过iota进行位移。

package main

import "fmt"

const (
    isCaptain = 1 << iota
    isTrooper
    isMedic

    canFlyMars
    canFlyJupiter
    canFlyMoon
)

func main() {
    var roles byte = isCaptain | isMedic | canFlyJupiter
    //打印二进制表示。
    fmt.Printf("%b\n", roles)
    fmt.Printf("%b\n", isCaptain)
    fmt.Printf("%b\n", isTrooper)
    fmt.Printf("%b\n", isMedic)

    fmt.Printf("是船长吗?%v\n", isCaptain&roles == isCaptain)
    fmt.Printf("是士兵吗?%v", isTrooper&roles == isTrooper)

}
英文:

Also, this is a pretty effective way to store different roles in one location in a byte, where the first value is set to 1, bit shifted by an iota.

package main

import &quot;fmt&quot;

const (
	isCaptain = 1 &lt;&lt; iota
	isTrooper
	isMedic

	canFlyMars
	canFlyJupiter
	canFlyMoon
)

func main() {
	var roles byte = isCaptain | isMedic | canFlyJupiter
	//Prints a binary representation.
	fmt.Printf(&quot;%b\n&quot;, roles)
	fmt.Printf(&quot;%b\n&quot;, isCaptain)
	fmt.Printf(&quot;%b\n&quot;, isTrooper)
	fmt.Printf(&quot;%b\n&quot;, isMedic)

	fmt.Printf(&quot;Is Captain? %v\n&quot;, isCaptain&amp;roles == isCaptain)
	fmt.Printf(&quot;Is Trooper? %v&quot;, isTrooper&amp;roles == isTrooper)

}

答案13

得分: 4

我这样创建了枚举。假设我们需要一个表示性别的枚举。可能的值有男性、女性、其他。

package gender

import (
	"fmt"
	"strings"
)

type Gender struct {
	g string
}

var (
	Unknown = Gender{}
	Male    = Gender{g: "male"}
	Female  = Gender{g: "female"}
	Other   = Gender{g: "other"}
)

var genders = []Gender{
	Unknown,
	Male,
	Female,
	Other,
}

func Parse(code string) (parsed Gender, err error) {
	for _, g := range genders {
		if g.g == strings.ToLower(code) {
			if g == Unknown {
				err = fmt.Errorf("unknown gender")
			}
			parsed = g
			return
		}
	}

	parsed = Unknown
	err = fmt.Errorf("unknown gender", code)
	return
}

func (g Gender) Gender() string {
	return g.g
}
英文:

I created the enum this way. Suppose we need an enum representing gender. Possible values are Male, Female, Others

package gender

import (
	&quot;fmt&quot;
	&quot;strings&quot;
)

type Gender struct {
	g string
}

var (
	Unknown = Gender{}
	Male    = Gender{g: &quot;male&quot;}
	Female  = Gender{g: &quot;female&quot;}
	Other   = Gender{g: &quot;other&quot;}
)

var genders = []Gender{
	Unknown,
	Male,
	Female,
	Other,
}

func Parse(code string) (parsed Gender, err error) {
	for _, g := range genders {
		if g.g == strings.ToLower(code) {
			if g == Unknown {
				err = fmt.Errorf(&quot;unknown gender&quot;)
			}
			parsed = g
			return
		}
	}

	parsed = Unknown
	err = fmt.Errorf(&quot;unknown gender&quot;, code)
	return
}

func (g Gender) Gender() string {
	return g.g
}

答案14

得分: 1

一个我发现的更简单的工作方式。

const (
Stake TX = iota
Withdraw)


type TX int

func (t TX) String() string {
return [...]string{"STAKE", "WITHDRAW"}[t]}

log.Println(Stake.String()) --&gt; STAKE
英文:

A simpler way I have found to work.

const (
Stake TX = iota
Withdraw)


type TX int

func (t TX) String() string {
return [...]string{&quot;STAKE&quot;, &quot;WITHDRAW&quot;}[t]}

log.Println(Stake.String()) --&gt; STAKE

huangapple
  • 本文由 发表于 2013年1月21日 00:07:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/14426366.html
匿名

发表评论

匿名网友

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

确定