enumconstiota
  1. 为什么要使用枚举,没了它就不行嘛?
  2. 如何在 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 语言中使用枚举?

enumconstiota
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
iotaiotaconstiotaint