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 26 Golang
基于Go Int转string几种方式性能测试
Apr 28 Golang
解决Golang time.Parse和time.Format的时区问题
Apr 29 Golang
解决golang post文件时Content-Type出现的问题
May 02 Golang
解决golang结构体tag编译错误的问题
May 02 Golang
Goland使用Go Modules创建/管理项目的操作
May 06 Golang
go web 预防跨站脚本的实现方式
Jun 11 Golang
go goroutine 怎样进行错误处理
Jul 16 Golang
Go语言实现一个简单的并发聊天室的项目实战
Mar 18 Golang
Golang使用Panic与Recover进行错误捕获
Mar 22 Golang
基于Python实现西西成语接龙小助手
Aug 05 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 将字符串按大写字母分隔成字符串数组
2010/04/30 PHP
php中DOMElement操作xml文档实例演示
2013/03/26 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
PHP开发中解决并发问题的几种实现方法分析
2017/11/13 PHP
基于SVG的web页面图形绘制API介绍及编程演示
2013/06/28 Javascript
Knockout text绑定DOM的使用方法
2013/11/15 Javascript
js获取域名的方法
2015/01/27 Javascript
jQuery中closest和parents的区别分析
2015/05/07 Javascript
jquery控制表单输入框显示默认值的方法
2015/05/22 Javascript
解决angular的$http.post()提交数据时后台接收不到参数值问题的方法
2015/12/10 Javascript
node.js与C语言 实现遍历文件夹下最大的文件,并输出路径,大小
2017/01/20 Javascript
原生javascript实现的全屏滚动功能示例
2017/09/19 Javascript
bootstrap treeview 扩展addNode方法动态添加子节点的方法
2017/11/21 Javascript
nodejs搭建本地服务器轻松解决跨域问题
2018/03/21 NodeJs
JS简单实现查看文档创建日期、修改日期和文档大小的方法示例
2018/04/08 Javascript
nodejs图片处理工具gm用法小结
2018/12/12 NodeJs
Python爬虫抓取手机APP的传输数据
2016/01/22 Python
关于Python 3中print函数的换行详解
2017/08/08 Python
pycharm 将python文件打包为exe格式的方法
2019/01/16 Python
使用Python向C语言的链接库传递数组、结构体、指针类型的数据
2019/01/29 Python
python通过paramiko复制远程文件及文件目录到本地
2019/04/30 Python
对pyqt5中QTabWidget的相关操作详解
2019/06/21 Python
Django中的用户身份验证示例详解
2019/08/07 Python
django创建超级用户过程解析
2019/09/18 Python
django 获取字段最大值,最新的记录操作
2020/08/09 Python
python hmac模块验证客户端的合法性
2020/11/07 Python
护士岗前培训自我评鉴
2014/02/28 职场文书
大课间体育活动方案
2014/03/12 职场文书
关于读书的演讲稿800字
2014/08/27 职场文书
公司股东合作协议书
2014/09/14 职场文书
2014年党的群众路线整改措施思想汇报
2014/10/12 职场文书
2014年政工师工作总结
2014/12/18 职场文书
MySQL 使用事件(Events)完成计划任务
2021/05/24 MySQL
Redis+Lua脚本实现计数器接口防刷功能(升级版)
2022/02/12 Redis
python中filter,map,reduce的作用
2022/06/10 Python
HTML 里 img 元素的 src 和 srcset 属性的区别详解
2023/05/21 HTML / CSS