十年网站开发经验 + 多家企业客户 + 靠谱的建站团队
量身定制 + 运营维护+专业推广+无忧售后,网站问题一站解决
这篇文章主要介绍了Golang中如何实现枚举的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Golang中如何实现枚举文章都会有所收获,下面我们一起来看看吧。
我们一直强调成都网站建设、网站设计对于企业的重要性,如果您也觉得重要,那么就需要我们慎重对待,选择一个安全靠谱的网站建设公司,企业网站我们建议是要么不做,要么就做好,让网站能真正成为企业发展过程中的有力推手。专业网站设计公司不一定是大公司,创新互联作为专业的网络公司选择我们就是放心。
在编程领域里,枚举用来表示只包含有限数量的固定值的类型,在开发中一般用于标识错误码或者状态机。拿一个实体对象的状态机来说,它通常与这个对象在数据库里对应记录的标识状态的字段值相对应。
if (article.state == 2) { // state 2 代表文章已发布 }
假如我们的代码里没有注释,或者等我们项目的代码里充斥着这些魔术数字的判断的时候,你是不是会很头疼?
后来我就学会了把这些状态值定义成常量,并且也搞一个判断对象状态的方法单独封装这段逻辑。
public class ArticleState { public static final int Draft = 1; //草稿 public static final int Published = 2; //发布 public static final int Deleted = 3; // 已删除 } public Boolean checkArticleState(int state) { ... }
这种用法,肯定是比在程序里直接用魔术数字进行判断要强很多啦,至少看着不会很头疼,不会想骂**。
不过后来被当时带我的老大哥说这种也有缺点,上面这个 checkArticleState 方法用来检查文章状态,本意是让调用者传入 ArticleState 的三个静态常量之一,但由于没有类型上的约束,因此传入任意一个 int 值在语法上也是允许的,编译器也不会提出任何警告,用枚举更合适一些。
em~! 我不记得大学教 Java 的那个学期老师讲过这玩意啊,莫非又是一个上课玩手机错过的知识点?所以使用枚举后我们的Java代码变成了:
// 使用enum而非class声明 public enum ArticleState { //要在enum里创建所有的枚举对象 Draft(1, "草稿"); Published(2, "已发布"); Deleted(3, "已删除") // 自定义属性 private int code; private String text; // 构造方法必须是private的 ArticleState(int code, String text) { this.code = id; this.text = name; } } public Boolean checkArticleState(ArticleState state) { ... }
这样就能靠形参的枚举类型帮我们过滤掉非法的状态值,把整型值作为参数传给 checkArticleState 方法时因为类型不匹配编译不过去,在写代码是编译器也能马上提示出来。
如果没有用过 Java 的小伙伴也不用纠结,主要语法点我用注释标注出来了,大家应该都能看懂。
后来这两年主要在用Go做项目,我发现相似的问题 Go 里存在,但是 Go 并没有提供枚举类型,那怎么做到进行状态值的正确限制呢?如果还是用 int 型的常量肯定不行。比如:
const ( Draft int = 1 Published = 2 Deleted = 3 ) const ( Summer int = 1 Autumn = 2 Winter = 3 Spring = 4 ) func main() { // 输出 true, 不会有任何编译错误 fmt.Println(Autumn == Draft) }
比如上面定义了两组 int 类型的常量,一类代表文章状态,一类代表季节的四季。这种方式拿文章状态与季节进行比较不会有任何编译上的错误。
答案在 Go 内置库或者一些咱们都知道的开源库的代码里就能找到。比如看看 google.golang.org/grpc/codes 里的gRPC 的错误码是怎么定义的,就能明白该怎么正确的实现枚举。
我们可以用 int 作为基础类型创建一个别名类型,Go 里边是支持这个的
type Season int const ( Summer Season = 1 Autumn = 2 Winter = 3 Spring = 4 )
当然定义连续的常量值的时候 Go 里边经常使用 iota,所以上面的定义还能进一步简化。
type Season int const ( Summer Season = iota + 1 Autumn Winter Spring ) type ArticleState int const ( Draft int = iota + 1 Published Deleted ) func checkArticleState(state ArticleState) bool { // ... } func main() { // 两个操作数类型不匹配,编译错误 fmt.Println(Autumn == Draft) // 参数类型不匹配,但是因为 ArticleState 底层的类型是 int 所以传递 int 的时候会发生隐式类型转换,所以不会报错 checkArticleState(100) }
虽然这些状态值的底层的类型都是 int 值,但是现在进行两个不相干类型的枚举值比较,会造成编译错误,因为现在我们使用状态值的地方都有了类型限制。
不过函数 checkArticleState 的参数类型设置成了 ArticleState 但是因为 ArticleState 底层的类型是 int 。所以调用 checkArticleState 时传递 int 类型的参数会发生隐式类型转换,不会造成编译报错,这块如果想解决,只能重新定义类型来实现了。
关于“Golang中如何实现枚举”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“Golang中如何实现枚举”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注创新互联行业资讯频道。