GO

时间:2016-03-29 15:39:34

标签: go enums iota

我正在尝试为我定义的类型生成枚举

type FeeStage int

this我了解到我可以使用iota创建基于此类型的枚举

const(
     Stage1 FeeStage = iota
     Stage2 
     Stage3
)

然而,操纵枚举的实际值相当麻烦且容易出错

const(
     Stage1 FeeStage = iota           // 0
     Stage2          = iota + 6       // 7
     Stage3          = (iota - 3) * 5 // -5
)

有没有办法自动将带有自定义值的ENUM列表转换为某种类型。这是我以前使用的,但只将常量的第一个成员转换为自定义类型。

const(
     Stage1 FeeStage = 1
     Stage2          = 2
     Stage3          = 2
)

Here是一个结果相似的游乐场

3 个答案:

答案 0 :(得分:6)

除了使用iota和自动枚举,或做最直接的事情之外别无他法:

const(
     Stage1 FeeStage = 1
     Stage2 FeeStage = 2

     // or another syntax with same results
     Stage3 = FeeStage(2)
)

哪个笨蛋比做iota + 5之类的东西要麻烦,正如你所说的那样非常糟糕。

如果值超出程序上下文的重要性,我通常使用iota,或者如果我需要在协议中使用的值,则使用显式输入。

虽然我不得不说有时只使用整数或字符串就足够了,但这取决于上下文。例如,参见http status codes in the standard library。它们没有特殊类型。

答案 1 :(得分:2)

您应该澄清一下您实际想要使用枚举常量做什么,但看起来您正试图将任意值分配给您的自定义类型。

如果构造常量并初始化要排序并遵循模式,则使用iota并不需要很麻烦。 Effective Go也有相关内容。

您可以为枚举常量创建相当复杂的模式,这些模式不一定容易出错并且很麻烦。

答案 2 :(得分:1)

实际上还有一种方法。但是,首先要清楚一些事情。

constant declarations中,如果存在类型,则常量将采用指定的类型:

const n int64 = 3 // n will be a typed constant, its type will be int64

如果省略类型,则常量将采用表达式的类型:

const x = int16(3) // x will be a typed constant, its type will be int16

如果表达式是无类型常量,则声明的常量将保持无类型常量:

const i = 1 // i will be an untyped integer constant

请注意,如果您尝试打印i类型(例如使用fmt.Printf("%T", i),则会看到int,这是因为传递常量时对于函数或将其赋值给变量时,必须将其转换为实际类型,并使用默认类型(因为fmt.Println()的参数类型为interface{}) - 这是{{ 1}}表示无类型的整数常量。

在带括号的int声明列表中,表达式列表可以从声明中省略(第一个除外)。如果表达式缺失,将使用先前的非空表达式(文本替换)。

所以当你这样做时:

const

这意味着:

const(
    Stage1 FeeStage = iota
    Stage2 
    Stage3
)

其中包含3个新常量:const ( Stage1 FeeStage = iota Stage2 FeeStage = iota Stage3 FeeStage = iota ) Stage1Stage2,均为Stage3类型。

你的第二个例子:

FreeStage

由于您没有省略表达式,您的第一个常量const ( Stage1 FeeStage = iota // 0 Stage2 = iota + 6 // 7 Stage3 = (iota - 3) * 5 // -5 ) 将是一个类型化常量(Stage1类型),其余的将是无类型的常量!所以这甚至没有资格(不符合你的要求)!

现在到了你的观点:你想要这样的东西:

FreeStage

如上所述,如果省略类型,const( Stage1 FeeStage = 1 Stage2 = 2 Stage3 = 2 ) Stage2将是无类型常量。因此必须指定类型,您可以利用const规范是:

这一事实
Stage3

您可以指定标识符列表

ConstSpec      = IdentifierList [ [ Type ] "=" ExpressionList ] .

这更具可读性吗?也许只有一些常数。如果有很多,请使用Not_a_Golfer的建议:

const(
    Stage1, Stage2, Stage3 FeeStage = 1, 2, 2
)