我开始学习其他语言。 Go有一个非常elegant way of creating constants的数字值,如:
const (
_ = iota // 0 and is skipped
Sunday // 1
Monday // 2
...
)
这很容易编写,但是它很容易维护吗?例如,如果您突然在当前之间插入新值,则后续所有值都将更改其值。它很难找到,只有严格的差异读取才能揭示它。或其他部分的错误。如何使用名称提取这些值并在程序的其他部分或数据库中使用? 例如,对于PostgreSQL,我可以定义:
CREATE TYPE color AS ENUM ('', 'Sunday', 'Monday');
只是为了说明一个想法。例如,Python has Enum类型:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
然后您可以像Color.RED
一样使用它。接下来我可以采用所有值:
list(Color)
[<Color.RED: 1>, <Color.BLUE: 2>, <Color.GREEN: 3>]
这让我能够内省&#34;模块化并在数据库中创建易于阅读的枚举。例如,对于PostgreSQL,我可以定义:
CREATE TYPE color AS ENUM ('RED', 'GREEN', 'BLUE');
我怎么能:
感谢。
答案 0 :(得分:3)
1)您可以使用stringer生成名称https://godoc.org/golang.org/x/tools/cmd/stringer
2)不确定你是什么意思?大多数语言都允许你漂移值,你应该总是添加到列表的末尾,如果你想让数字保持不变,或者像在python中你可以明确地将每个值设置为数字而不是使用iota。
3)不是真的,在golang中,enums并不是很好。
答案 1 :(得分:2)
只是一个建议,但在你的情况下可能会有所帮助:我发现如果很明显值看起来像位掩码,那么常量不太可能在以后更改/破坏,你可以在像这样:
const (
Red = 1 << iota
Green
Blue
) // values = 1, 2, 4
而且,即使它不是最漂亮的声明,你也可以包括掩码常量
const (
Red, RedMask = 1 << iota, 1<< iota - 1 // Red = 1, RedMask = 0
Green, GreenMask // Green = 2, mask = 1
Blue, BlueMask // 4, 3
RGB, RGBMask // 8, 7
)
这与这些常量的指定type
结合使用可能很有用:
type ColourConst int
const (
Red, RMask ColourConst = 1 << iota, 1 << iota-1
// ...
_, All
)
// something like this (untested, might not be correct)
func (c ColourConst) validate() error {
mask := int(c) & (-1 * int(c))
if mask != int(c) {
return errors.New("Colour is not a single bit value")
}
if s := c & All; s != c {
return errors.New("Colour is not in range")
}
}
我知道一周中的日子不太可能被用作位掩码,但它使人们不太可能破坏代码。至少,它传达了常数的顺序很重要,这是IMO iota
的作用。
答案 2 :(得分:0)
解。 有优秀的模块Enumer和Enumelinter