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 个新常量: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
和 Stage3
将是无类型常量。因此必须指定类型,您可以利用以下事实: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
)
我正在尝试为我定义的类型生成一个枚举
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 个新常量: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
和 Stage3
将是无类型常量。因此必须指定类型,您可以利用以下事实: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
)