Go语言中现阶段没有枚举,可以使用const常量配合上一节《Go语言常量》中介绍的iota来模拟枚举,请看下面的代码:

typeWeaponintconst(ArrowWeapon=iota//开始生成枚举值,默认为0ShurikenSniperRifleRifleBlower)//输出所有枚举值fmt.Println(Arrow,Shuriken,SniperRifle,Rifle,Blower)//使用枚举类型并赋初值varweaponWeapon=Blowerfmt.Println(weapon)

代码输出如下:
1234
4

代码说明如下:
第1行中将int定义为Weapon类型,就像枚举类型其实本质是一个int一样。当然,某些情况下,如果需要int32和int64的枚举,也是可以的。

第4行中,将Array常量的类型标识为Weapon,这样标识后,const下方的常量可以是默认类型的,默认时,默认使用前面指定的类型作为常量类型。该行使用iota进行常量值自动生成。iota起始值为0,一般情况下也是建议枚举从0开始,让每个枚举类型都有一个空值,方便业务和逻辑的灵活使用。

一个const声明内的每一行常量声明,将会自动套用前面的iota格式,并自动增加。这种模式有点类似于电子表格中的单元格自动填充。只需要建立好单元格之间的变化关系,拖动右下方的小点就可以自动生成单元格的值。

当然,iota不仅只生成每次增加1的枚举值。我们还可以利用iota来做一些强大的枚举常量值生成器。下面的代码可以方便生成标志位常量:

const(FlagNone=1<<iotaFlagRedFlagGreenFlagBlue)fmt.Printf("%d%d%dn",FlagRed,FlagGreen,FlagBlue)fmt.Printf("%b%b%bn",FlagRed,FlagGreen,FlagBlue)

代码输出如下:
248
101001000

在代码中编写一些标志位时,我们往往手动编写常量值,如果常量值特别多时,很容易重复或者写错。因此,使用ioto自动生成较为方便。

代码说明如下:

  • 第2行中iota使用了一个移位操作,每次将上一次的值左移一位,以做出每一位的常量值。
  • 第8行,将3个枚举按照常量输出,分别输出2、4、8,都是将1每次左移一位的结果。
  • 第9行,将枚举值按二进制格式输出,可以清晰地看到每一位的变化。
将枚举值转换为字符串

枚举在C#语言中是一个独立的类型,可以通过枚举值获取值对应的字符串。例如,C#中Week枚举值Monday为1,那么可以通过Week.Monday.ToString()函数获得Monday字符串。

Go语言中也可以实现这一功能,见下面的例子。

转换字符串:

packagemainimport"fmt"//声明芯片类型typeChipTypeintconst(NoneChipType=iotaCPU//中央处理器GPU//图形处理器)func(cChipType)String()string{switchc{caseNone:return"None"caseCPU:return"CPU"caseGPU:return"GPU"}return"N/A"}funcmain(){//输出CPU的值并以整型格式显示fmt.Printf("%s%d",CPU,CPU)}

运行结果:
CPU1

代码说明如下:

  • 第6行,将int声明为ChipType芯片类型。
  • 第9行,将const里定义的一句常量值设为ChipType类型,且从0开始,每行值加1。
  • 第14行,定义ChipType类型的方法String(),返回字符串。
  • 第15~22行,使用switch语句判断当前的ChitType类型的值,返回对应的字符串。
  • 第30行,输出CPU的值并按整型格式输出。

使用String()方法的ChipType在使用上和普通的常量没有区别。当这个类型需要显示为字符串时,Go语言会自动寻找String()方法并进行调用。