设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间16 现在时间16 缓存数据 我什么都可以扛住 就是扛不住对你的喜欢

我什么都可以扛住 就是扛不住对你的喜欢 -- 喜欢

查看: 1030|回复: 1

Golang中如何实现枚举详析

[复制链接]

  离线 

TA的专栏

  • 打卡等级:常驻代表
  • 打卡总天数:30
  • 打卡月天数:0
  • 打卡总奖励:373
  • 最近打卡:2025-04-22 10:44:22
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
419
主题
369
精华
0
金钱
1584
积分
852
注册时间
2023-2-10
最后登录
2025-4-22

发表于 2024-7-26 10:29:11 | 显示全部楼层 |阅读模式
Golang中怎么实现枚举?下面本篇文章给大家介绍一下Golang中实现枚举的方法,希望对大家有所帮助!
在编程领域里,枚举用来表示只包含有限数量的固定值的类型,在开发中一般用于标识错误码或者状态机。拿一个实体对象的状态机来说,它通常与这个对象在数据库里对应记录的标识状态的字段值相对应。
在编程领域里,枚举用来表示只包含有限数量的固定值的类型,在开发中一般用于标识错误码或者状态机。拿一个实体对象的状态机来说,它通常与这个对象在数据库里对应记录的标识状态的字段值相对应。
在刚开始学编程的时候,你一定写过,至少见过直接使用魔术数字进行判断的代码。啥叫魔术数字呢,举个例子,要置顶一个文章的时候先判断文章是不是已发布状态。
  1. if (article.state == 2) {
  2.    // state 2 代表文章已发布
  3. }
复制代码
假如我们的代码里没有注释,或者等我们项目的代码里充斥着这些魔术数字的判断的时候,你是不是会很头疼?
后来我就学会了把这些状态值定义成常量,并且也搞一个判断对象状态的方法单独封装这段逻辑。
  1. public class ArticleState {
  2.     public static final int Draft = 1; //草稿
  3.     public static final int Published = 2; //发布
  4.     public static final int Deleted = 3; // 已删除
  5. }

  6. public  Boolean checkArticleState(int state) {
  7.     ...
  8. }
复制代码
这种用法,肯定是比在程序里直接用魔术数字进行判断要强很多啦,至少看着不会很头疼,不会想骂**。
不过后来被当时带我的老大哥说这种也有缺点,上面这个 checkArticleState 方法用来检查文章状态,本意是让调用者传入 ArticleState 的三个静态常量之一,但由于没有类型上的约束,因此传入任意一个 int 值在语法上也是允许的,编译器也不会提出任何警告,用枚举更合适一些。
em~! 我不记得大学教 Java 的那个学期老师讲过这玩意啊,莫非又是一个上课玩手机错过的知识点?所以使用枚举后我们的Java代码变成了:
  1. // 使用enum而非class声明
  2. public enum ArticleState {
  3.     //要在enum里创建所有的枚举对象
  4.     Draft(1, "草稿");
  5.     Published(2, "已发布");
  6.     Deleted(3, "已删除")

  7.     // 自定义属性
  8.     private int code;
  9.     private String text;

  10.     // 构造方法必须是private的
  11.     ArticleState(int code, String text) {
  12.         this.code = id;
  13.         this.text = name;
  14.     }
  15. }

  16. public  Boolean checkArticleState(ArticleState state) {
  17.     ...
  18. }
复制代码
这样就能靠形参的枚举类型帮我们过滤掉非法的状态值,把整型值作为参数传给 checkArticleState 方法时因为类型不匹配编译不过去,在写代码是编译器也能马上提示出来。
如果没有用过 Java 的小伙伴也不用纠结,主要语法点我用注释标注出来了,大家应该都能看懂。
后来这两年主要在用Go做项目,我发现相似的问题 Go 里存在,但是 Go 并没有提供枚举类型,那怎么做到进行状态值的正确限制呢?如果还是用 int 型的常量肯定不行。比如:
  1. const (
  2.     Draft int = 1
  3.     Published = 2
  4.     Deleted   = 3
  5. )

  6. const (
  7.     Summer int = 1
  8.     Autumn     = 2
  9.     Winter     = 3
  10.     Spring     = 4
  11. )

  12. func main() {
  13.     // 输出 true, 不会有任何编译错误
  14.     fmt.Println(Autumn == Draft)
  15. }
复制代码
比如上面定义了两组 int 类型的常量,一类代表文章状态,一类代表季节的四季。这种方式拿文章状态与季节进行比较不会有任何编译上的错误。
答案在 Go 内置库或者一些咱们都知道的开源库的代码里就能找到。比如看看 google.golang.org/grpc/codes 里的gRPC 的错误码是怎么定义的,就能明白该怎么正确的实现枚举。
我们可以用 int 作为基础类型创建一个别名类型,Go 里边是支持这个的
  1. type Season int
  2. const (
  3.     Summer Season = 1
  4.     Autumn        = 2
  5.     Winter        = 3
  6.     Spring        = 4
  7. )
复制代码
当然定义连续的常量值的时候 Go 里边经常使用 iota,所以上面的定义还能进一步简化。
  1. type Season int
  2. const (
  3.     Summer Season = iota + 1
  4.     Autumn
  5.     Winter
  6.     Spring
  7. )

  8. type ArticleState int
  9. const (
  10.   Draft int = iota + 1
  11.   Published
  12.   Deleted 
  13. )

  14. func checkArticleState(state ArticleState) bool {
  15.     // ...
  16. }

  17.  func main() {
  18.    // 两个操作数类型不匹配,编译错误
  19.    fmt.Println(Autumn == Draft)
  20.     // 参数类型不匹配,但是因为 ArticleState 底层的类型是 int 所以传递 int 的时候会发生隐式类型转换,所以不会报错
  21.    checkArticleState(100)
  22.  }
复制代码
虽然这些状态值的底层的类型都是 int 值,但是现在进行两个不相干类型的枚举值比较,会造成编译错误,因为现在我们使用状态值的地方都有了类型限制。
不过函数 checkArticleState 的参数类型设置成了 ArticleState 但是因为 ArticleState 底层的类型是 int 。所以调用 checkArticleState 时传递 int 类型的参数会发生隐式类型转换,不会造成编译报错,这块如果想解决,只能重新定义类型来实现了
总结
到此这篇关于Golang中如何实现枚举的文章就介绍到这了,更多相关Golang实现枚举内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

等级头衔

等級:晓枫资讯-列兵

在线时间
0 小时

积分成就
威望
0
贡献
0
主题
0
精华
0
金钱
11
积分
2
注册时间
2024-6-13
最后登录
2024-6-13

发表于 2025-4-7 07:08:03 | 显示全部楼层
感谢楼主分享。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表