GO 中自定义类型的枚举

ENUMs for custom types in GO

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

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 是一个结果相似的游乐场

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

const(
     Stage1 FeeStage = 1
     Stage2 FeeStage = 2

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

恕我直言,这比做 iota + 5 这样的事情要简单得多,正如你所说,这真的很糟糕。

如果值在程序上下文之外不重要,我通常使用 iota,或者如果我需要在协议或其他东西中使用这些值,我通常使用显式类型。

虽然我不得不说有时只使用整数或字符串就足够了,但这取决于上下文。例如参见 [​​=13=]。他们没有特殊类型。

您或许应该阐明您实际想要对枚举常量执行的操作,但看起来您正试图为您的自定义类型分配任意值。

如果您构造常量和要排序的初始化并遵循某种模式,那么使用 iota 并不需要很麻烦。 Effective Go 也有这方面的部分。

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

其实是有办法的。但让我们先弄清楚一些事情。

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{})- 对于一个 int无类型整数常量。

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

所以当你这样做时:

const(
    Stage1 FeeStage = iota
    Stage2 
    Stage3
)

意思是:

const (
    Stage1 FeeStage = iota
    Stage2 FeeStage = iota
    Stage3 FeeStage = iota
)

这会产生 3 个新常量:Stage1Stage2Stage3,它们都是 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
)

如上所述,如果省略类型,Stage2Stage3 将是无类型常量。因此必须指定类型,您可以利用以下事实:const 规范是:

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

您可以指定一个标识符 list:

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

这样更易读吗?也许如果只有几个常量。如果有很多,使用Not_a_Golfer的推荐:

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