【问题标题】:ENUMs for custom types in GOGO 中自定义类型的枚举
【发布时间】:2016-07-17 06:42:27
【问题描述】:

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

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

【问题讨论】:

标签: go enums iota


【解决方案1】:

除了使用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。他们没有特殊的类型。

【讨论】:

  • 或者没有语法只是 "const Stage1 = 1; varOfTypeFeeStage = Stage1" 在某些情况下也可以工作。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    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 ] .
    

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

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

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

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

    【讨论】:

    • 这是一个很好的接触,但对我个人来说感觉不太可读 - 我认为 2-3 consts 是有用的限制。在 2-3 时,实际上并没有重复这种类型。但这是一个品味问题。无论如何,很好的答案!
    • @Not_a_Golfer 我同意。我自己不会使用它,我会把它放在 3 行中。但这是一种可能。
    猜你喜欢
    • 2011-09-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多