在Golang的标准语法中并没有专门的枚举类型,不过我们可以通过常量结合iota标识符来模拟实现枚举的效果,这种方式灵活且能满足绝大多数业务场景的枚举使用需求。

iota的基础用法
iota是Golang中的一个常量计数器,只能在const关键字修饰的常量块中使用,从0开始自动递增,每新增一行常量声明,iota的值就会加1。我们可以借助这个特性快速定义一组连续的枚举值。
package main
import "fmt"
// 定义星期枚举
const (
Monday = iota // 0
Tuesday // 1
Wednesday // 2
Thursday // 3
Friday // 4
Saturday // 5
Sunday // 6
)
func main() {
fmt.Println("Monday的值是:", Monday)
fmt.Println("Sunday的值是:", Sunday)
}
自定义枚举起始值
iota的默认起始值是0,如果想要从其他值开始,只需要在第一个常量声明时给iota做加法或者赋值即可,后续常量会自动延续递增逻辑。
package main
import "fmt"
// 定义状态码枚举,从100开始
const (
StatusSuccess = iota + 100 // 100
StatusFailed // 101
StatusPending // 102
StatusCancel // 103
)
func main() {
fmt.Println("StatusSuccess的值是:", StatusSuccess)
fmt.Println("StatusCancel的值是:", StatusCancel)
}
跳过枚举中的某个值
如果枚举序列中需要跳过某个值,可以使用下划线_占位,此时iota仍然会正常递增,但是不会给占位符赋值,从而实现跳值的效果。
package main
import "fmt"
const (
A = iota // 0
B // 1
_ // iota变为2,但是不赋值给任何常量
C // 3
D // 4
)
func main() {
fmt.Println("A:", A, "B:", B, "C:", C, "D:", D)
}
位运算枚举的实现
在实际开发中,我们经常会遇到一个属性可以有多个枚举值组合的场景,比如权限控制,这时候可以用位运算结合iota来实现,每个枚举值对应一个二进制位。
package main
import "fmt"
// 定义权限枚举,每个值对应一个二进制位
const (
ReadPermission = 1 << iota // 1,二进制0001
WritePermission // 2,二进制0010
ExecutePermission // 4,二进制0100
DeletePermission // 8,二进制1000
)
func main() {
// 组合读写权限
userPermission := ReadPermission | WritePermission
fmt.Println("用户权限值:", userPermission)
// 判断是否包含读权限
hasRead := userPermission&ReadPermission != 0
fmt.Println("是否有读权限:", hasRead)
}
常量枚举的使用注意事项
- iota只能在const块中使用,在普通代码块或者函数中使用会直接编译报错。
- 如果const块中某一行手动赋值了非iota相关的数值,后续没有显式声明iota的常量会使用这个手动赋值的值,不会继续递增。
- 为了让枚举更易用,通常会给枚举类型定义别名,然后实现String方法,方便打印时输出枚举的含义而不是数值。
下面是实现枚举String方法的示例:
package main
import "fmt"
type Weekday int
const (
Monday Weekday = iota
Tuesday
Wednesday
Thursday
Friday
Saturday
Sunday
)
// 实现String方法,方便打印枚举含义
func (w Weekday) String() string {
switch w {
case Monday:
return "Monday"
case Tuesday:
return "Tuesday"
case Wednesday:
return "Wednesday"
case Thursday:
return "Thursday"
case Friday:
return "Friday"
case Saturday:
return "Saturday"
case Sunday:
return "Sunday"
default:
return "Unknown"
}
}
func main() {
fmt.Println(Monday)
fmt.Println(Sunday)
}