Go语言是没有 enum 这个枚举关键字的。
那 Go 语言里面又是怎么处理枚举这个问题的呢?
我们这篇文章讲解下!
需要枚举的场景
我们在处理人的姓名的时候,一般都是男或者女,或者最大再加一个未知,不会有其他类型吧。
像上面这种常见,我们一般就会使用枚举处理。
我们会定义一个变量,希望他能只能赋 男、女、未知 这三种值。
如果是在其他语言:
代码语言:javascript复制from enum import Enum
class Sex(Enum):
man = 1
woman = 2
unknown = 3
然后在使用的时候就可以直接 Sex.main
直接调用。
Go 的实现
在 Go 语言中,我们如果要实现枚举,则需要使用常量计数器 iota 结合 const 来实现。
iota 是 go 语言的常量计数器,只能在 const 里面使用。
比如:
代码语言:javascript复制const(
SexMan = iota
SexWoman
SexUnknown
)
func main() {
fmt.Println(SexMan,SexWoman,SexUnknown)
}
// 执行结果
$ go run main.go
0 1 2
首先我们知道 const 是用来定义常量的,后面接括号就是定义一组常量。
我们给第一个常量赋值为 iota,在这组常量中,之后的常量就会为我们自动赋值递增。
iota有啥特点?
iota 在 const 关键字出现时,在 const 内部的第一行之前就被初始化为 0 了,const 中每增加一行常量声明就将自动加 1 ,哪怕是 _ 这种声明。
代码语言:javascript复制const(
SexMan = iota
SexWoman
_
SexUnknown
)
func main() {
fmt.Println(SexMan,SexWoman,SexUnknown)
}
// 执行结果
$ go run main.go
0 1 3
你会发现,最后一个变量的值变了。
其他情况
还会出现这种情况
代码语言:javascript复制const(
SexMan = iota
SexWoman = "woman"
SexUnknown
)
func main() {
fmt.Println(SexMan,SexWoman,SexUnknown)
}
// 执行结果
$ go run main.go
0 woman woman
在出现了 iota 的常量定义中,如果有一个值被特殊赋值后,后面的值都会一样。
解决办法就是在需要恢复计数的地方再次赋值 iota 即可:
代码语言:javascript复制const(
SexMan = iota
SexWoman = "woman"
SexUnknown = iota
SexUnknown1
)
func main() {
fmt.Println(SexMan,SexWoman,SexUnknown,SexUnknown1)
}
// 执行结果
$ go run main.go
0 woman 2 3
技巧升级
我们在定义枚举时,常常会显示的声明其类型,比如这样:
代码语言:javascript复制type Sex int
const(
SexMan Sex = iota
SexWoman
SexUnknown
)
为什么要这样做呢?
这样做有一个好处,我们可以对我们的 Sex 类型进行扩展。
比如这样:
代码语言:javascript复制type Sex int
func (this Sex) String() string {
switch this {
case 0:
return "男"
case 1:
return "女"
default:
return "未知"
}
}
const(
SexMan Sex = iota
SexWoman
SexUnknown
)
func main() {
fmt.Println(SexMan,SexWoman,SexUnknown)
}
// 执行结果
$ go run main.go
男 女 未知
fmt 在 println 时会去调用这个变量的 String 方法,于是打印就会出现男、女、未知了。
当然你还可以根据你的需要,进行扩展哇。
你学废了么?