概述
实际编程中我们经常会定义很多的常量(枚举),这是一个非常好的习惯。
但在golang中,由于没有枚举类型的概念,使得在赋值时会出现无效的枚举值。
比如下面这段json中内容:
{
"id": 1236,
"weekday": 100
}
weekday取值100已经超出了星期的范围。解析此结构体不会引起任何错误。事实上,由于变量类型是一个int,100也是一个合法的值。
由于Go中的枚举是使用类型别名构造的,因此我们无法实现对枚举值的限制。
解决方法
要检查提供的weekday字段值是否合法,我们可以针对该值(≤7)实现一个自定义的检查方法。
还有另一种方法就是在最后声明一个end常量并像下面这样实现一个有效性的检查函数:
type Weekday uint32
const (
Unknown Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
end //①
)
func (w Weekday) isValid() bool {
return w < end //②
}
① 私有常量
② 将值和end比较
注意:常量end将保持未被导出状态(即私有状态),以便外部包不能使用它。
在这个实现中,有效性检查是基于和end常量比较实现的。
即使新的Weekday类型值被加入,只要我们保持end常量是在枚举列表的最后一行,那么isValid方法将始终告诉我们提供的值是否是被视为一个有效的值:
fmt.Println(Monday.isValid()) //true
fmt.Println(Weekday(2).isValid()) //true
fmt.Println(Weekday(100).isValid()) //false
总结
关于枚举值的处理,有下面一些我们需要注意:
-
我们应该总是定义一个特定的类型
-
如果我们不关心枚举值,我们可以使用常量生成器iota来简化定义。
-
unkown应该始终分配给零值
-
要检查枚举值的有效性,我们可以通过在最后一行定义一个私有常量来实现。