• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

小技巧分享在-Go-如何实现枚举

php 搞代码 3年前 (2022-02-28) 62次浏览 已收录 0个评论
文章目录[隐藏]

大家好,我是煎鱼。

在日常的业务工程开发中,咱们经常会有应用枚举值的诉求,枚举控的好,测试值边界一遍过…

有的小伙伴会说,在 Go 语言不是有 iota 类型做枚举吗,那煎鱼你这篇文章还讲什么?

讲道理,Go 语言并没有 enum 关键字,有用过 Protobuf 等的小伙伴晓得,Go 语言只是 ”无限的枚举“ 反对,咱们也会用常量来定义,枚举值也须要有字面意思的映射。

示例

在一些业务场景下,是没法达到咱们的诉求的。示例如下:

type FishType int

const (
 A FishType = iota
 B
 C
 D
)

func main() {
 fmt.Println(A, B, C, D)
}

输入后果为:“0 1 2 3”。这时候就一脸懵逼了…枚举值,应该除了键以外,还得有个对应的值。也就是这个 “0 1 2 3” 别离对应着什么含意,是不是应该输入 ”A B C D“

但 Go 语言这块就没有间接的撑持了,因而这不是一个残缺的枚举类型的实现。

同时假如咱们传入超过 FishType 类型申明范畴的枚举值,在 Go 语言中默认也不会有任何管制,是失常输入的。

上述这种 Go 枚举实现,在某种状况下是不齐全的,严格意义上不能成为 enum(枚举)。

应用 String 做枚举

如果要反对枚举值的对应输入的话,咱们能够通过如下形式:

type FishType int

const (
 A FishType = iota
 B
 C
 D
)

func (f FishType) String() string {
 return [...]string{"A", "B", "C", "D"}[f]
}

运行程序:

func main() {
 var f FishType = A
 fmt.Println(f)
 switch f {
 case A:
  fmt.Println("脑子进煎鱼了")
 case B:
  fmt.Println("记得点赞")
 default:
  fmt.Println("别别别...")
 }
}

输入后果:

A
脑子进煎鱼了

咱们能够借助 Go 中 String 办法的默认约定,针对于定义了 String 办法的类型,默认输入的时候会调用该办法。

这样就能够达到取得枚举值的同时,也能拿到其映射的字面意思。

主动生成 String

但每次手动编写还是比拟麻烦的。在这一块,咱们能够利用官网提供的 cmd/string 来疾速实现。

咱们装置如下命令:

go install golang.org/x/tools/cmd/stringer

在所需枚举值上设置 go:generate 指令:

//go:generate stringer -type=FishType
type FishType int

在我的项目根目录执行:

go generate ./...

会在根目录生成 fishtype\_string.go 文件:

.
├── fishtype_string.go
├── go.mod
├── go.sum
└── main.go

fishtype\_string 文件内容:

package main

import "strconv"

const _FishType_name = "ABCD"

var _FishType_index = [...]uint8{0, 1, 2, 3, 4}

func (i FishType) String() string {
 if i < 0 || i >= FishType(len(_FishType_index)-1) {
  return "FishType(" + strconv.FormatInt(int64(i), 10) + ")"
 }
 return _FishType_name[_FishType_index[i]:_FishType_index[i+1]]
}

所生成进去的文件,次要是依据枚举值和映射值做了个映射,且针对超出枚举值的场景进行了判断:

func main() {
 var f1 FishType = A
 fmt.Println(f1)
 var f2 FishType = E
 fmt.Println(f2)
}

执行 go run . 查看程序运行后果:

$ go run .
A
FishType(4)

总结

在明天这篇文章中,咱们介绍了如何在 Go 语言实现规范的枚举值,尽管有些繁琐,但整体不会太难。

也有小伙伴曾经在社区中提出了 ”proposal: spec: add typed enum support“ 的提案,置信将来有机会能看到 Go 本身反对 enum(枚举)的那一天。

你平时会怎么在业务代码中实现枚举呢,欢送大家一起留言交换:)

欢送大家在评论区留言和交换 :)

若有任何疑难欢送评论区反馈和交换,最好的关系是相互成就,各位的点赞就是煎鱼创作的最大能源,感激反对。

文章继续更新,能够微信搜【脑子进煎鱼了】浏览,本文 GitHub github.com/eddycjy/blog 已收录,学习 Go 语言能够看 Go 学习地图和路线,欢送 Star 催更。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:小技巧分享在-Go-如何实现枚举

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址