Skip to content

在 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 递增,想要跳值就用 _ 占位。

参考资料 ​

相关页面 ​

Hello Golang