Go 语言没有 enum
关键字的,通过使用 const
& iota
可以实现枚举的能力。本篇文章将探讨几个问题:
- 为什么要使用枚举,没了它就不行嘛?
- 如何在 Go 语言中优雅的使用枚举。
为什么要使用枚举?
Stackoverflow 上有个问题 What are enums and why are they useful? 中的回答很具备说服力。
当一个变量(尤其是一个方法的参数)仅能取自一个很小的选择集合中时,就应该使用枚举。例如类型常量(合同状态: "permanent", "temp", "apprentice")或者标记(“执行中”、“延后执行”)等。
当使用枚举去替代整数时,运行时会去检查传入的参数是否是合法参数(是否在定义的枚举集合当中),避免错误的传入了一个不可用的常量。
举例来讲,第一种实现,通过文档来备注每个数字的含义:
/** Counts number of foobangs.
* @param type Type of foobangs to count. Can be 1=green foobangs,
* 2=wrinkled foobangs, 3=sweet foobangs, 0=all types.
* @return number of foobangs of type
*/
public int countFoobangs(int type)
调用该方法的时候:
int sweetFoobangCount = countFoobangs(3);
通过文档来备注每种状态的数字代号这种方案,在大型开发中着实是让人头疼的,况且并不见得文档中写的和代码中实际是一致的。人员流动交接常常会遗漏许多东西,慢慢的谁都不愿意再来维护这个项目。但使用枚举来实现的话,就变得清晰易懂,且避免了出错。
/** Types of foobangs. */
public enum FB_TYPE {
GREEN, WRINKLED, SWEET,
/** special type for all types combined */
ALL;
}
/** Counts number of foobangs.
* @param type Type of foobangs to count
* @return number of foobangs of type
*/
public int countFoobangs(FB_TYPE type)
调用方法的时候:
int sweetFoobangCount = countFoobangs(FB_TYPE.SWEET);
这种方案就很清晰,代码自带说明性,开发 & 维护起来都很方便。
如何在 Go 语言中使用枚举?
如开篇所言,Go 语言中没有 enum
类型,但我们可以通过 const
& iota
来实现。go 源码中有一段就是很好的示例代码。使用步骤如下:
- 定义枚举类型
- 设定该枚举类型的可选值集合,可以借助
iota
的能力来简化赋值流程
type FileMode uint32
const (
// The single letters are the abbreviations
// used by the String method's formatting.
ModeDir FileMode = 1 << (32 - 1 - iota) // d: is a directory
ModeAppend // a: append-only
ModeExclusive // l: exclusive use
ModeTemporary // T: temporary file; Plan 9 only
ModeSymlink // L: symbolic link
ModeDevice // D: device file
ModeNamedPipe // p: named pipe (FIFO)
ModeSocket // S: Unix domain socket
ModeSetuid // u: setuid
ModeSetgid // g: setgid
ModeCharDevice // c: Unix character device, when ModeDevice is set
ModeSticky // t: sticky
ModeIrregular // ?: non-regular file; nothing else is known about this file
// Mask for the type bits. For regular files, none will be set.
ModeType = ModeDir | ModeSymlink | ModeNamedPipe | ModeSocket | ModeDevice | ModeCharDevice | ModeIrregular
ModePerm FileMode = 0777 // Unix permission bits
)
最后再着重说一下 iota
的用法。
iota
代表了一个连续的整形常量,0,1,2,3 ...iota
将会被重置为 0 ,当再一次和const
搭配使用的时候iota
所定义的值类型为int
,它会在每次赋值给一个常量后自增