Golang中能否像Java的Enum一样对常量进行分组?

Golang中能否像Java的Enum一样对常量进行分组? 根据我所了解的,Go语言将常量视为具有类型的不可修改变量。但我想知道是否可以将相关的常量分组,就像Java使用枚举那样?例如,假设我想要MONTH_TYPE(一年中的月份)和WEEKDAY_TYPE(星期日、星期一等)。Go语言允许这样做吗?

8 回复

尽管我已在代码中见过这种做法,但我并不赞同,因为比较字符串比比较整数耗时更长。

更多关于Golang中能否像Java的Enum一样对常量进行分组?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


关于这个问题有很多讨论:https://github.com/golang/go/issues/6386 但在常量中使用类型似乎带来的问题比解决的问题更多。

为什么没有人提到过这种模式?

type Foo int

const (
  VariantA Foo = iota
  VariantB
  VariantC
)

附注:来自手机,因此可能包含自动"校正"。

所以你的偏好是将这个定义为int类型,并且为了打印目的,创建一个调用者为Weekday的函数,该函数可能基于切片(或数组)进行打印。好的,我能理解这一点。

func main() {
    fmt.Println("hello world")
}

我会为它们实现 fmt.Stringerfmt.GoStringer 接口。这比让一个字符串溜过去要好得多,否则在修复常量值中的拼写错误后,稍后会破坏你的代码!

func main() {
    fmt.Println("hello world")
}

我觉得这有所不同。那个讨论希望将常量扩展到非基本类型。Java中的枚举本质上是常量,但它们为常量组提供了类型。这类似于Go在定义自定义类型为Foo(实际上是字符串或结构体)时已经实现的功能,但会应用于一组常量(这些常量仍然可以初始化为字符串等)。目前看来答案是否定的。Go不支持一组常量拥有自己的类型(我猜这相当于常量具有Foo类型,而Foo被定义为String类型,这大概是不允许的?)

type Foo string
const x Foo = "x"  // 这样允许吗?

是的,这是允许的,其行为方式符合人们的预期:

type Weekday string

const (
	Monday    Weekday = "Monday"
	Tuesday           = "Tuesday"
	Wednesday         = "Wednesday"
	Thursday          = "Thursday"
	Friday            = "Friday"
)

请参见此示例。该代码无法编译,因为 Monday 是一个常量,您无法为其分配新值。

您所不具备的是非基本类型的常量。由于这包括基本类型的数组和切片,上面的示例可能看起来有些奇怪,因为字符串可转换为 rune 切片。

是的,Go语言支持通过const块和iota标识符对相关常量进行分组,这类似于Java枚举的分组功能。你可以使用iota自动生成递增的常量值,从而创建逻辑上分组的常量集合。以下是一个示例,展示如何定义月份和星期几的常量分组。

示例代码:使用常量分组

package main

import "fmt"

// 定义月份常量分组
const (
    January = iota + 1 // iota从0开始,加1使January为1
    February
    March
    April
    May
    June
    July
    August
    September
    October
    November
    December
)

// 定义星期几常量分组
const (
    Sunday = iota // iota从0开始,Sunday为0
    Monday
    Tuesday
    Wednesday
    Thursday
    Friday
    Saturday
)

func main() {
    // 使用月份常量
    fmt.Printf("January: %d\n", January)  // 输出: January: 1
    fmt.Printf("December: %d\n", December) // 输出: December: 12

    // 使用星期几常量
    fmt.Printf("Sunday: %d\n", Sunday)    // 输出: Sunday: 0
    fmt.Printf("Monday: %d\n", Monday)    // 输出: Monday: 1
}

在这个示例中:

  • 月份常量从1开始递增(使用iota + 1),对应1月到12月。
  • 星期几常量从0开始递增(使用iota),对应星期日到星期六。
  • 每个const块定义了一个逻辑分组,常量在块内自动赋值。

这种方法提供了类型安全和编译时检查,类似于Java枚举的分组行为。如果需要更复杂的枚举行为(如添加方法),可以使用自定义类型和常量结合。

回到顶部