什么是枚举

枚举(Enumeration)是一种常见的编程概念,它定义了一组命名常量。我们知道在 Go 语言中定义常量是这样的形式:

const (
	A = "a"
	B = "b"
)

开发者可以使用枚举创建复杂的、有限的常量集,这些常量集具有有意义的名称和唯一的值。


枚举语法示例

enum
constiotaconst[iota]()
constiota
const (
	 Monday int = iota      // Monday  = 0
	 Tuesday               // Tuesday = 1
	 Wednesday             // Wednesday = 2
	 Thursday              // Thursday = 3
	 Friday                // Friday = 4
	 Saturday              // Saturday =5
	 Sunday                // Sunday = 6
)
iota

枚举的使用疑问

对于刚接触枚举的,应该会有以下疑问:

枚举与常量的区别

const
const
const (
	 Monday     int = 0            // Monday  = 0
	 Tuesday    int = 1            // Tuesday = 1
	 Wednesday  int = 2            // Wednesday = 2
	 Thursday   int = 3            // Thursday = 3
	 Friday     int = 4            // Friday = 4
	 Saturday   int = 5            // Saturday =5
	 Sunday     int = 6            // Sunday = 6
)
constconstWednesday  int = 1const + iota

枚举值的作用

Mondayint0

枚举本身的值没有什么意义,它是用来模拟现实中的某些只能取固定值的变量的,对应一个值只是在计算机中比较好处理。

枚举值只能为整形?

iotaiota

下面看一个 C++ 枚举示例:

//枚举类型必须是整形吗,不能是浮点数或是别的类型?
enum E
    {
        monday=-2,
        tuesday=1.5//有么有非int类型的枚举?
    };

上面的枚举值定义为负数、浮点数,这种写法是错误的。在任何语言中,枚举值只能是整形。


枚举高级用法

从 1 开始枚举

如果不希望枚举值从 0 开始,从1 开始,可以在 Go 这样实现:

const (
	 Monday = iota + 1     // Monday  = 1
	 Tuesday               // Tuesday = 2
	 Wednesday             // Wednesday = 3
	 Thursday              // Thursday = 4
	 Friday                // Friday = 5
	 Saturday              // Saturday = 6
	 Sunday                // Sunday = 7
)

自定义枚举值

iota
const (
	 Monday = iota + 1     // Monday = 0 + 1 = 1
	 Tuesday = iota + 2    // Tuesday = 1 + 2 = 3
	 Wednesday = iota * 2  // Wednesday = 2 * 2 = 2
	 Thursday              // Thursday = 3
	 Friday                // Friday = 4
	 Saturday              // Saturday =5
	 Sunday                // Sunday = 6
)
enumiota

跳过值的枚举

如果想要跳过某个值,可以使用 _ 字符,即忽略的意思

const (
	 Monday = iota         // Monday = 0 
   _                     // 1 被跳过
	 Tuesday               // Tuesday = 2
	 Wednesday             // Wednesday = 3
	 Thursday              // Thursday = 4
   _                     // 5 被跳过
	 Friday                // Friday = 6
	 Saturday              // Saturday = 7
	 Sunday                // Sunday = 8
)

枚举使用场景

下面举例几个枚举的使用场景,加深枚举的作用和使用。

限制参数类型

当处理状态码时,如果不使用枚举

const (
	Normal       = 200
	Forbid       = 403
	NetworkError = 502
)

// 该函数形参是整形
func HandlerStatus(statusCode int) {
	fmt.Println(statusCode)
}

// 调用 HandlerStatus 随便什么整数都可以
func main() {
	HandlerStatus(Normal)
	HandlerStatus(404)
}

结果:
200
404
HandlerStatusNormalForbidNetworkError

下面看看使用枚举是否能达到效果?

enum
// int 别名
type Code int

const (
	Normal Code = iota
	Forbid
	NetworkError
)

func HandlerStatus(statusCode Code) {
	fmt.Println(statusCode)
}

func main() {
	HandlerStatus(Normal)
	var notFount int = 1
	// 这里会导致程序编译失败,因为 notFount 不是 Code 类型
	HandlerStatus(notFount)
}
HandlerStatus

使用 string 作为枚举值

iota
// 声明一个 week 类型
type week int

const (
	 Monday week = iota    // Monday  = 0
	 Tuesday               // Tuesday = 1
	 Wednesday             // Wednesday = 2
	 Thursday              // Thursday = 3
	 Friday                // Friday = 4
	 Saturday              // Saturday =5
	 Sunday                // Sunday = 6
)

func main() {
	var w week = Monday
	switch w {
	case Monday:
		fmt.Println(Monday)
	case Tuesday:
		fmt.Println(Tuesday)
	}
}

输出结果:
0

可以发现直接打印出了该枚举常量的枚举值 0,但是 0 并不是很容易理解该枚举常量的意义。

StringString
// 声明一个 week 类型
type week int

const (
	 Monday week = iota    // Monday  = 0
	 Tuesday               // Tuesday = 1
	 Wednesday             // Wednesday = 2
	 Thursday              // Thursday = 3
	 Friday                // Friday = 4
	 Saturday              // Saturday =5
	 Sunday                // Sunday = 6
)

// 实现 week 类型的 String() 方法
func (w week) String() string {
		return [...]string{"星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期日"}[w]
}

func main() {
	var w week = Monday
	switch w {
	case Monday:
		fmt.Println(Monday)
	case Tuesday:
		fmt.Println(Tuesday)
	}
}

输出结果:
星期一
String

总结

enumconstiota

同时很多开发者会忽略枚举的使用,因为枚举并不是必须使用的,完全可以直接常量来替代。但是枚举的使用提高程序可读性,严谨性等,所以在项目中使用枚举最好能够了解枚举的使用场景以及一些特定用法。