Golang表示枚举类型的详细讲解


Posted in Golang onSeptember 04, 2021

Golang表示枚举类型的详细讲解

枚举,是一种重要的数据类型,由一组键值对组成,通常用来在编程语言中充当常量的标识符。在主流行编程语言如 c、 java 等,都有原生支持。在 go 中,大家却找不到 enum 或者其它直接用来声明枚举类型的关键字。从熟悉其它编程语言的开发者转用 go 编程,刚开始会比较难接受这种情况。其实,如果你看到如何在 go 中表示枚举类型时,可能会感受到 go 语言设计者对简洁性、问题考虑的深度,是一般资浅工程师无法比拟的。

其实,在 go 语言设计者的眼里,enum 本质是常量,为什么要多余一个关键字呢?在 go 只是没有 enum 关键字而已,其表现枚举的形式,与其它语言别无太大区别。下面来看看如果在 go 中表示枚举。

学习、使用一门语言,是学习、理解语言本身的设计哲学,同时也会感受到设计者的性格特点。

基础工作 

为了下面讲解方便,这里使用 go modules 的方式先建立一个简单工程。

~/Projects/go/examples  
➜  mkdir enum  
~/Projects/go/examples  
➜  cd enum  
~/Projects/go/examples/enum  
➜  go mod init enum  
go: creating new go.mod: module enum  
~/Projects/go/examples/enum  
➜  touch enum.go

const + iota

以 启动、运行中、停止 这三个状态为例,使用 const 关键来声明一系列的常量值。在 enum.go 中写上以下内容:

package main  
import "fmt"  
const (  
    Running int = iota  
    Pending  
    Stopped  
)  
func main() {  
    fmt.Println("State running: ", Running)  
    fmt.Println("State pending: ", Pending)  
    fmt.Println("State Stoped: ", Stopped)  
}

保存并运行,可以得到以下结果,

~/Projects/go/examples/enum   
➜  go run enum.go  
State running:  0  
State pending:  1  
State Stoped:  2

在说明发生了什么之前,我们先看来一件东西,iota。相比于 c、java,go 中提供了一个常量计数器,iota,它使用在声明常量时为常量连续赋值。

比如这个例子,

const (  
    a int = iota // a = 0  
    b int = iota // b = 1  
    c int = iota // c = 2  
)  
const d int = iota // d = 0

在一个 const 声明块中,iota 的初始值为 0,每声明一个变量,自增 1。以上的代码可以简化成:

const (  
    a int = iota // a = 0  
    b // b = 1  
    c // c = 2  
)  
const d int = iota // d = 0

设想一下,如果此时有 50 或者 100 个常量数,在 c 和 java 语言中写出来会是什么情况。

关于 iota,有更多的具体的技巧(例如跳数),详细请看官方定义 iota。

通过使用 const 来定义一连串的常量,并借助 iota 常量计数器,来快速的为数值类型的常量连续赋值,非常方便。虽然没有了 enum 关键字,在这种情况下发现,是多余的,枚举本质上就是常量的组合。

当然,你可以使用以下方式,来更接近其它语言的 enum,

// enum.go  
...  
type State int  
const (  
    Running State = iota  
    Pending  
    Stopped  
)  
...

把一组常量值,使用一个类型别名包裹起来,是不是更像其它语言中的 enum {} 定义了呢?

你还可以将上面的例子改为:

// enum.go  
...  
type State int 
const (  
    Running State = iota  
    Pending  
    Stopped  
)  
func (s State) String() string {  
    switch s {  
    case Running:  
        return "Running"  
    case Pending:  
        return "Pending"  
    case Stopped:  
        return "Stopped"  
    default:  
        return "Unknown" 
     }  
}  
...

为定义的枚举类型加上 String 函数,运行结果如下:

~/Projects/go/examples/enum   
➜  go run enum.go  
State running:  Running  
State pending:  Pending  
State Stoped:  Stopped

是不是很魔幻,思路一下又开阔一些,长见识了。把实际的值与打印字符分开,一般语言设计者不会想到。看到这里,有没有这种的感觉,go 语言的设计者并不是偷懒,而是为了可以偷懒想了很多、做了很多。

到此这篇关于Golang表示枚举类型的详细讲解的文章就介绍到这了,更多相关Golang 枚举类型内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Golang 相关文章推荐
Go各时间字符串使用解析
Apr 02 Golang
golang interface判断为空nil的实现代码
Apr 24 Golang
Golang 正则匹配效率详解
Apr 25 Golang
Golang 空map和未初始化map的注意事项说明
Apr 29 Golang
Golang: 内建容器的用法
May 05 Golang
Golang 实现获取当前函数名称和文件行号等操作
May 08 Golang
Go语言实现Snowflake雪花算法
Jun 08 Golang
Go遍历struct,map,slice的实现
Jun 13 Golang
详解Go语言Slice作为函数参数的使用
Jul 02 Golang
Go语言空白表示符_的实例用法
Jul 04 Golang
Golang gRPC HTTP协议转换示例
Jun 16 Golang
Go语言测试库testify使用学习
Jul 23 Golang
golang 语言中错误处理机制
Aug 30 #Golang
Golang并发操作中常见的读写锁详析
Aug 30 #Golang
Go中的条件语句Switch示例详解
Aug 23 #Golang
Go Plugins插件的实现方式
Aug 07 #Golang
使用GO语言实现Mysql数据库CURD的简单示例
Aug 07 #Golang
go使用Gin框架利用阿里云实现短信验证码功能
Aug 04 #Golang
手把手教你导入Go语言第三方库
Aug 04 #Golang
You might like
php小型企业库存管理系统的设计与实现代码
2011/05/16 PHP
php切割页面div内容的实现代码分享
2012/07/31 PHP
深入解析PHP内存管理之谁动了我的内存
2013/06/20 PHP
php数组保存文本与文本反编成数组实例
2014/11/13 PHP
php简单socket服务器客户端代码实例
2015/05/18 PHP
PHP实现截取中文字符串不出现?号的解决方法
2016/12/29 PHP
php中遍历二维数组并以表格的形式输出的方法
2017/01/03 PHP
php 广告点击统计代码(php+mysql)
2018/02/21 PHP
JavaScript 常见对象类创建代码与优缺点分析
2009/12/07 Javascript
JavaScript 原型继承
2011/12/26 Javascript
重写javascript中window.confirm的行为
2012/10/21 Javascript
js兼容的placeholder属性详解
2013/08/18 Javascript
JQuery选中checkbox方法代码实例(全选、反选、全不选)
2015/04/27 Javascript
Javascript实现快速排序(Quicksort)的算法详解
2015/09/06 Javascript
利用JS实现点击按钮后图片自动切换的简单方法
2016/10/24 Javascript
js实现界面向原生界面发消息并跳转功能
2016/11/22 Javascript
JavaScript代码执行的先后顺序问题
2017/10/29 Javascript
微信小程序使用Promise简化回调
2018/02/06 Javascript
Angular 5.x 学习笔记之Router(路由)应用
2018/04/08 Javascript
js动态设置select下拉菜单的默认选中项实例
2018/08/21 Javascript
Vue实现移动端左右滑动效果的方法
2018/11/27 Javascript
JavaScript实现轮播图效果代码实例
2019/09/28 Javascript
微信小程序实现比较功能的方法汇总(五种方法)
2020/03/07 Javascript
Vue Router中应用中间件的方法
2020/08/06 Javascript
Python的Tornado框架的异步任务与AsyncHTTPClient
2016/06/27 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
python中的迭代和可迭代对象代码示例
2017/12/27 Python
python 扩展print打印文件路径和当前时间信息的实例代码
2019/10/11 Python
Python计算指定日期是今年的第几天(三种方法)
2020/03/26 Python
Python特殊属性property原理及使用方法解析
2020/10/09 Python
澳大利亚吉他在线:Artist Guitars
2017/03/30 全球购物
为什么group by 和order by会使查询变慢
2014/05/16 面试题
写一个方法,输入一个文件名和一个字符串,统计这个字符串在这个文件中出现的次数
2016/04/13 面试题
大学生自荐信
2013/12/11 职场文书
遗嘱继承权公证书
2015/01/26 职场文书
Docker下安装Oracle19c
2022/04/13 Servers