在Go中如何在有限的值范围内实现类型安全枚举?
例如,假设我想用简单的尺寸和颜色对t恤衫进行建模,这两种t恤衫都有有限的可能值,以确保我无法创建具有不受支持的值的实例。
我可以声明类型大小
和颜色
基于字符串
,定义有效值的枚举,以及使用它们的TShirt
类型:
type Size string
const (
Small Size = "sm"
Medium = "md"
Large = "lg"
// ...
)
type Color string
const (
Red Color = "r"
Green = "g"
Blue = "b"
// ...
)
type TShirt struct {
Size Size
Color Color
}
var mediumBlueShirt = TShirt{Medium, Blue}
但是,我如何确保没有创建尺寸/颜色未定义的T恤?
var doNotWant = TShirt{"OutrageouslyLarge", "ImpossibleColor"}
不直接支持有限集合枚举,但是您可以使用类型系统来实现:
// Exported interface
type Size interface {
// Unexported method
isSize()
}
// unexported type
type size struct {
sz string
}
func (s size) String() string {return s.sz}
// Implement the exported interface
func (size) isSize() {}
var (
Small Size = size{"small"}
Large Size = size{"large"}
)
这样,您只能使用预先声明的值。
这通常不值得麻烦。考虑针对已知值集验证此类枚举。
如果使枚举基于整数,则可以创建可用于检查有效性的伪值:
type Size int
const (
Small Size = iota
Medium
Large
maxSize // Always keep this at the end
)
var sizeToString = map[Size]string{
Small: "sm",
Medium: "md",
Large: "lg",
}
func (s Size) String() string {
return sizeToString[s]
}
func (s Size) Valid() bool {
return s > 0 && s < maxSize
}
如果您在const块的末尾保留maxsize
,则您的Valid
函数将始终工作,即使在添加或删除枚举值之后也是如此。
您可以对第二个枚举类型执行相同的操作,并且您的复合类型还可以定义一个Valid
函数,如果两个枚举都有效,该函数将返回true。
当我使用这个模式时,我总是包含一个单元测试,以确保每个枚举值都有一个字符串转换,这样我就不会忘记。您可以通过从0到maxsize
创建一个for循环来实现这一点,并检查您是否从未从sizeToString
中获得空字符串。
问题内容: Scala没有enumJava所具有的类型安全的。给定一组相关的常数,Scala中代表这些常数的最佳方法是什么? 问题答案: http://www.scala-lang.org/docu/files/api/scala/Enumeration.html 使用范例
枚举类(“新的枚举”/“强类型的枚举”)主要用来解决传统的C++枚举的三个问题: 传统C++枚举会被隐式转换为int,这在那些不应被转换为int的情况下可能导致错误 传统C++枚举的每一枚举值在其作用域范围内都是可见的,容易导致名称冲突(同名冲突) 不可以指定枚举的底层数据类型,这可能会导致代码不容易理解、兼容性问题以及不可以进行前向声明 枚举类(enum)(“强类型枚举”)是强类型的,并且具有类
问题内容: 基本上,我所做的是为州写一个枚举,我不仅希望能够像州一样访问它们,而且还希望访问它们的缩写以及它们是否是原始殖民地。 这似乎按我预期的那样工作。我可以 对于涉及枚举的特定情况,这是执行此操作的最佳方法,还是设置和格式化此枚举的更好方法?预先感谢所有人! 问题答案: 首先,枚举方法不应大写。它们是与其他方法一样的方法,具有相同的命名约定。 其次,您所做的并不是建立枚举的最佳方法。不要为每
为什么我在浏览java时看不到
问题内容: 假设是,我将如何产生给定序数的枚举值? 问题答案: 足够了。一条线; 足够简单。