专栏首页JackieZhengGo语言学习——三分钟看透iota

Go语言学习——三分钟看透iota

源起枚举

最近做需求时,有一个需要枚举的场景,大概有10+个枚举类型,不愿意像定义一个开关那样敷衍的写成

const (
    SwitchOff = 0
    SwitchOn  = 1
)

显得不够精致~

于是想到了iota,深入了解了下,这个小东西好像有点东西。

再回到需求本身——枚举。有了iota,就不用显示定义一大堆数值了。

未使用iota版本

const (
  ColorRed         = 0
  ColorOrange 		= 1
  ColorYellow 		= 2
  ColorGrassland 	= 3
  ColorCyan 		= 4
  ColorBlue 		= 5
  ColorPurple 		= 6
)

使用iota版本

const (
  ColorRed 		= iota
  ColorOrange 		
  ColorYellow 		
  ColorGrassland 	
  ColorCyan 			
  ColorBlue 			
  ColorPurple 		
)

两者的效果是一样的,各个枚举对应的值也是一样的。iota是从0开始,每一行都是往下递增。乍一看,iota还显得挺高端。

施展威力的同时,iota也有大家诟病的地方。

比如这时候如果需要添加一个"灰色"的枚举类型,在未使用iota版本里面不管在什么位置插入这个枚举,定义一个具体数值即可,比如对应7。

使用iota版本里面如果加在ColorPurple后面,对应的值就是7,没有问题。

但是如果在其他位置,那就会打破原来的平衡,比如放在ColorGrassland后

const (
  ColorRed 		= iota		// 0
  ColorOrange 				// 1
  ColorYellow 				// 2
  ColorGrassland 			// 3
  ColorGray				// 4
  ColorCyan 				// 5
  ColorBlue 				// 6
  ColorPurple 				// 7
)

可以看出,从加入ColorGray后,从ColorCyan开始以及后面的枚举对应的值都变了。如果各个枚举的值在代码中已经hard code了,那这样的调整将是灾难性的。

iota虽然灵活,但似乎有点过于灵活了。

看到这,你以为你已经了解了iota,不,你没有,它比你想的还要灵活、复杂。

iota的花式玩法

首先来看一道送分题

const (
	AA = iota
	BB        
	_
	DD
)

问题

此时DD对应的值是多少?

稍稍推理下,显然不是2,因为中间还多了个下划线。

没错,DD对应的值是3。这里的下划线"_"表示跳过某值,原本对应在这个位置的值应该是2,但是获取它不重要,所以使用下划线跳过了,这个用法也和Go对应下划线的定义保持一致。

比如遍历map集合,不需要使用key值时,可以写成

for _, value := range testMap {
  fmt.Println(value)
}

好,再看下一题

const (
	AA = iota 
	BB        
	_
	DD = iota + 1
	EE
)

问题

此时DD和EE对应的值是多少?

与上例不同,这里在DD后面重新指定了DD = iota + 1,即在原有的数据上加1,所以此时DD的值为3+1=4。

后面EE没有重新定义,则也会顺延DD的规则递增1,即5。

如果上面一题你得到了正确的答案,那下面一题也不就不难了

const (
  AA = iota 
  BB        
  _
  DD = iota + 1
  EE
   FF = iota + 2
   GG = iota
)

问题

此时FF和GG对应的值是多少。

根据上一题,DD和EE分别对应4和5。

首先看这里的FF,注意这里的FF并不是顺延EE的值加1,然后再加2,如果是顺延则FF = 6 + 2 = 8。但是FF的值是7。

每当某个枚举被重置(即后面使用iota重新赋值时),则需要从第一个枚举数到当前的次序,比如这里从AA=0数到FF,此时FF的次序是5,然后再加2,即FF=5+2=7。

GG的值使用上面的方法,得到值为6。

注意:以上是我从结果反推得到的结论,一开始难以理解这里各个枚举对应的值,找到这个规则后,发现程序跑出来值和规则验证的一样。

下面看最后一道题

const (
	AA, BB = iota + 1, iota + 2
	CC, DD
)

问题

此时的AA、BB、CC和DD对应的值分别是多少

这里只需要明白一个规则,iota是每行才会加一。

所以这里第一行的iota都是0,则AA和BB对应的值分别是0+1=1和0+2=2。

下面的CC和DD都是顺延,对应的iota递增则为1,然后分别按照iota+1和iota+2的运算得到值为1+1 = 2和1+2 = 3。

好了,做完上面不管是送分题还是送命题,我想,你对iota这个小东西算是有一个真正的了解。

个人感觉,功能实现千万条,看懂再用第一条。

回到枚举

有时候我们使用枚举,不仅是定义它的值,还需要有对应的描述信息,我们知道这在Java里面是比较方便实现的,毕竟Java本来就有枚举的概念。

下面我们看看Go实现带有描述信息枚举的两种方式。

使用map映射

const (
	ColorRed 				= iota
      ColorOrange 		
      ColorYellow 		
      ColorGrassland 	
      ColorCyan 			
      ColorBlue 			
      ColorPurple 		
)

var ColorMap = map[int]string{
	ColorRed:       "赤",
	ColorOrange:    "橙",
	ColorYellow:    "黄",
	ColorGrassland: "绿",
	ColorCyan:      "青",
	ColorBlue:      "蓝",
	ColorPurple:    "紫",
}

这样,如果想获取ColorRed对应的描述信息,就可以写成ColorMap[ColorRed]。

定义枚举类型

type Color int
const (
	ColorRed 					Color	= iota
  ColorOrange 		
  ColorYellow 		
  ColorGrassland 	
  ColorCyan 			
  ColorBlue 			
  ColorPurple 		
)

func (c Color) String() string {
switch c {
  case ColorRed:
    return "赤"
  case ColorOrange:
      return "橙"
  case ColorYellow:
      return "黄"
  case ColorGrassland:
      return "绿"
  case ColorCyan:
      return "青"
  case ColorBlue:
      return "蓝"
  case ColorPurple:
      return "紫"
}

将颜色枚举定义为Color类型,则所有枚举值都是该类型,如果要获取ColorRed对应的描述信息,就可以写成ColorRed.String()。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hadoop阅读笔记(一)——强大的MapReduce

    前言:来园子已经有8个月了,当初入园凭着满腔热血和一脑门子冲动,给自己起了个响亮的旗号“大数据 小世界”,顿时有了种世界都是我的,世界都在我手中的赶脚。可是.....

    JackieZheng
  • Java豆瓣电影爬虫——减少与数据库交互实现批量插入

      节前一个误操作把mysql中record表和movie表都清空了,显然我是没有做什么mysql备份的。所以,索性我把所有的表数据都清空的,一夜回到解放前……...

    JackieZheng
  • 可视化(番外篇)——SWT总结

      本篇主要介绍如何在SWT下构建一个应用,如何安装SWT Designer并破解已进行SWT的可视化编程,Display以及Shell为何物、有何用,SWT中...

    JackieZheng
  • Go语言_iota用法

    在每一个const关键字出现时,被重置为0,然后再下一个const出现之前,每出现一次iota,其所代表的数字会自动增加1。

    Zoctopus
  • WebSocket在Spring Boot中的使用

    “WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务...

    小诸葛
  • 系统游戏运行库DirectX修复工具 v3.8 增强版

    (DirectX Repair)是一款系统级工具软件,简便易用。本程序无需安装,可直接运行。 本程序的主要功能是检测当前系统的DirectX状态,如果发现异常则...

    空木白博客
  • 华为海思,半导体的民族脊梁

    半导体产业是现代信息技术的基石,几乎任何的计算机,通讯设备,物联网,手机,乃至汽车,飞机,雷达,我们能够想象和不能想象的,都离不开一块块的芯片。2014年开始,...

    用户1564362
  • 【中篇】中国存储器:“无心插柳”的战略突围

    对于存储器产业,我们的理解盲区无处不在。很多人都知道全球DRAM产业规模在1000亿美金级别,但是应该没多少了解在25年前和4年前这个产业的规模?

    FPGA开源工作室
  • 机器人手术大势所趋,何日才能进医保?

    ? 尽管达芬奇手术机器人价格昂贵,需要2000多万元一台,然而全国各地却争先恐后地引进,据了解,目前国内宫引进了29台达芬奇手术机器人,因具有减轻患者痛苦、减...

    机器人网
  • 【GTC 2020】用GPU加速你在线语音识别(ASR)管道

    语音识别应用于Siri、谷歌Voice和Amazon Echo等云服务中,越来越受欢迎,这大大增加了对ASR推理的计算需求。我们现在正在为我们的gpu加速管道提...

    GPUS Lady

扫码关注云+社区

领取腾讯云代金券