5

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

type FeeStage int

这里我了解到我可以使用 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
)

是一个具有类似结果的操场

4

3 回答 3

8

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

const(
     Stage1 FeeStage = 1
     Stage2 FeeStage = 2

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

恕我直言,这比iota + 5你说的那样做真的很糟糕。

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

虽然我不得不说有时只使用整数或字符串就足够了,但这取决于上下文。例如,参见标准库中的 http 状态代码。他们没有特殊的类型。

于 2016-03-29T15:48:53.207 回答
2

您也许应该澄清您实际上想要对枚举常量做什么,但看起来您正在尝试为您的自定义类型分配任意值。

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

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

于 2016-03-29T15:50:40.947 回答
1

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

常量声明中,如果类型存在,常量将采用指定的类型:

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 个新常量:和Stage1,都属于 类型。Stage2Stage3FreeStage

你的第二个例子:

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则将Stage3是无类型常量。因此必须指定类型,您可以利用 const 规范是:

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

您可以指定一个标识符列表

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

这更具可读性吗?也许如果只有几个常数。如果有很多,请使用 Not_a_Golfer 的推荐:

const(
    Stage1 FeeStage = 1
    Stage2 FeeStage = 2
    Stage3 FeeStage = 2
)
于 2016-03-29T18:02:43.620 回答