Go中没有枚举那就自己实现

142 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情

枚举是一系列相同类型的常量的组合。枚举强大的功能被广泛的使用。然而,Go 中的枚举和其他编程语言的枚举有很多大区别。Go 没有像其他语言有 enum 关键字来标识枚举。但是我们可以使用 iota 来实现枚举。

iota 是什么

iota 是一个与常量一起使用的标识符,它可以简化使用自增数字的常量定义。 iota 关键字表示从零开始的整数常量。

iota 关键字表示连续的整数常量 0, 1, 2,…。每当源代码中出现单词 const 时,它都会重置为 0,并在每个 const 规范之后递增。

const (
    num0 = iota
    num1 = iota
    num2 = iota
)
func main() {
    fmt.Println(num0, num1, num2) //Print : 0 1 2
}

可以简化一下代码,不用每个常量都写入 iota。

const (
    num0 = iota
    num1 
    num2 
)
// 起始值不是从0开始
const (
    num0 = iota+1
    num1 
    num2 
)
// 通过下划线跳过某常量的值
const (
    num0 = iota+1
    _ 
    num2 
    num3
)

以上代码可以看出,如果常量列表起始值从 1 而不是 0 开始,您可以在算术表达式中使用 iota。如果想要跳过某个值,可以使用空白标识符跳过常量列表中的值。

使用 iota 实现枚举

type Weekday int
 const (
    Sun Weekday = iota+1
    Mon
    Tues
    Wed
    Thu
    Fri
    Sat 
)

以上是实现一个星期的枚举,但其值是数字,如果需要实现一个能够获取到值也是字符串的枚举呢?需要增加一个可以返回其字符串值的函数。


func (w Weekday) String() string{
    return [...]string{"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}[w-1]
}

func main() {                                        
   var weekday = Sunday                     
   fmt.Println(weekday) // Print : Sunday   
   fmt.Println(weekday.String()) // Print : Sunday 
}

总结

Golang 不直接支持枚举。 我们可以使用 iota 和常量来实现它。对于枚举的常量也是字符串时,要获取到真正的值需要增加一个能够返回字符串的函数。大概的实现步骤如下:

  • 声明一个新的自定义类型——整数类型。
  • 声明相关常量——使用 iota。
  • 创建通用行为——给类型一个字符串函数。

增加了一个返回字符串的函数,也可以支持其返回一个枚举对应的值的函数。即给类型一个 EnumIndex 函数。

func (w Weekday) EnumIndex() int { 
  return int(w) 
}
// 使用时只需要调用 EnumIndex 方法
func main(){
    fmt.Println(weekday.EnumIndex())
}