当前位置: 首页 > 后端技术 > Java

技巧分享:Go中如何实现枚举?

时间:2023-04-01 20:05:04 Java

大家好,我是炸鱼。在日常的业务工程开发中,我们经常会有使用枚举值的诉求。枚举控制的不错,测试值的边界又传过去了。。。有小伙伴会说Go语言没有枚举的iota类型嘛,炸鱼这文你还说啥?公平地说,Go语言没有enum关键字。用过Protobuf之类的朋友都知道,Go语言只支持“有限枚举”。我们也会用常量来定义,枚举值也需要有文字映射。示例在某些业务场景中,无法满足我们的需求。例子如下:typeFishTypeintconst(AFishType=iotaBCD)funcmain(){fmt.Println(A,B,C,D)}输出结果为:"0123"。这时候我就懵了……枚举值除了key应该还有一个对应的值吧。即“0123”对应什么意思,是否应该输出“ABCD”但是Go语言没有直接支持,所以这不是枚举类型的完整实现。同时,假设我们传入一个超出FishType类型声明范围的枚举值,在Go语言中默认是没有控制的,会正常输出。上面的Go枚举实现在某些情况下是不完整的,不能成为严格意义上的枚举。使用String进行枚举如果我们想要支持枚举值对应的输出,可以使用如下方法:typeFishTypeintconst(AFishType=iotaBCD)func(fFishType)String()string{return[...]string{"A","B","C","D"}[f]}运行程序:funcmain(){varfFishType=Afmt.Println(f)switchf{caseA:fmt.Println("我的大脑是炸鱼")caseB:fmt.Println("记得点赞")default:fmt.Println("不要,不要...")}}输出结果:A的大脑是炸了,我们可以借助Go中String方法的默认约定,对于定义了String方法的类型,默认输出的时候会调用这个方法。这样,在获取枚举值的同时,还可以获取其映射的字面意思。自动生成String但是每次手动写比较麻烦。在这方面,我们可以使用官方的cmd/string来快速实现。我们安装如下命令:goinstallgolang.org/x/tools/cmd/stringer在需要的枚举值上设置go:generate命令://go:generatestringer-type=FishTypetypeFishTypeint在项目根目录下执行:gogenerate./...会在根目录下生成fishtype\_string.go文件:.├──fishtype_string.go├──go.mod├──go.sum└──main.gofishtype\_string文件内容:packagemainimport"strconv"const_FishType_name="ABCD"var_FishType_index=[...]uint8{0,1,2,3,4}func(iFishType)String()string{如果我<0||i>=FishType(len(_FishType_index)-1){返回"FishType("+strconv.FormatInt(int64(i),10)+")"}return_FishType_name[_FishType_index[i]:_FishType_index[i+1]]}生成的文件主要是根据枚举值和映射值做映射,判断超出枚举值的场景:funcmain(){varf1FishType=Afmt.Println(f1)varf2FishType=Efmt.Println(f2)}执行gorun。查看程序运行结果:$gorun.AFishType(4)总结在今天的文章中,我们介绍了如何用Go语言实现标准的枚举值。总体难度不大。也有小伙伴在社区提出了“proposal:spec:addtypedenumsupport”的提案。我相信将来总有一天Go本身会支持enum(枚举)。你平时在业务代码中是如何实现枚举的?欢迎大家留言交流:)欢迎大家在评论区留言交流:)有什么问题欢迎在评论区反馈交流。最好的关系是相互成就,大家的点赞是创作炸鱼最大的动力,谢谢大家的支持。文章持续更新中。可以微信搜索【脑补炸鱼】阅读。本文已收录在GitHubgithub.com/eddycjy/blog中。学习Go语言可以看Go学习地图和路线。欢迎星星提醒。