在 Go 语言中,并没有像其他语言那样显式地提供枚举类型,但可以通过一些技巧和约定来实现类似的枚举效果。其中,iota 是一种特殊的预定义标识符,常用于定义枚举常量的递增值。
枚举类型的实现
写法是用 const 定义一组常量,iota 让它们依次递增。
使用 iota 定义枚举
go
package main
import "fmt"
// 定义枚举类型
type Weekday int
const (
Sunday Weekday = iota
Monday
Tuesday
Wednesday
Thursday
Friday
Saturday
)
func (d Weekday) String() string {
return [...]string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}[d]
}
func main() {
fmt.Println(Sunday) // 输出: Sunday(Weekday 实现了 String(),打印名称)
fmt.Println(Monday) // 输出: Monday
fmt.Println(Tuesday) // 输出: Tuesday
fmt.Println(Wednesday) // 输出: Wednesday
fmt.Println(Thursday) // 输出: Thursday
fmt.Println(Friday) // 输出: Friday
fmt.Println(Saturday) // 输出: Saturday
// 如需打印对应的整数值,可做显式转换
fmt.Println(int(Sunday), int(Saturday)) // 输出: 0 6
// 使用枚举类型
today := Wednesday
fmt.Printf("Today is %s\n", today) // 输出: Today is Wednesday
}iota 的应用
- 自动递增:
iota在const常量组中从 0 开始自动递增,每遇到一个新的const关键字重置为 0。 - 跳值使用:可以使用空白标识符
_来跳过某些值的定义。
示例
go
package main
import "fmt"
// 定义枚举类型
type FilePermission uint
const (
ReadPermission FilePermission = 1 << iota
WritePermission
ExecutePermission
)
func main() {
var p FilePermission = ReadPermission | WritePermission
fmt.Printf("Permission: %b\n", p) // 输出: Permission: 11
fmt.Println("Has Read permission?", p&ReadPermission == ReadPermission)
fmt.Println("Has Write permission?", p&WritePermission == WritePermission)
fmt.Println("Has Execute permission?", p&ExecutePermission == ExecutePermission)
}使用场景
- 状态码定义:HTTP 状态码、文件权限这类一组有限的取值。
- 选项和标志:配合
1 << iota写位掩码。
注意事项
iota只在const常量组内部有效,每遇到一个新的const关键字就会重置。
总结
状态码、权限位这类一组相关的常量,都用 const 加 iota 来定义:常量组内自动从 0 递增,想要跳值就用 _ 占位。