我正在尝试为我定义的类型生成枚举
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是一个结果相似的游乐场
答案 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
)
,Stage1
和Stage2
,均为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
)