Go语言 有没有一种方法可以迭代用作枚举常量

cuxqih21  于 2023-08-01  发布在  Go
关注(0)|答案(5)|浏览(117)

我正在尝试在golang中使用enum,如下所示。我正在努力寻找一种简单的方法来迭代常量值列表。在golang中,迭代用作枚举的常量值的常见做法是什么?谢谢你,谢谢

type DayOfWeek int
const(
       Monday DayOfWeek = iota
       Tuesday
       Wednesday
       Thursday
       Friday
       Saturday
       Sunday
      )

字符串
在Java中,我们可以像下面这样迭代。

public enum DayOfWeek {
    MONDAY, 
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
}

for (DayOfWeek day: DayOfWeek.values()) {
   // code logic
}

laawzig2

laawzig21#

没有直接的方法在运行时枚举命名类型的值/示例,无论是变量还是常量,除非您专门定义了一个列出它们的切片。这由枚举类型的定义者或用户决定。

package main

import (
    "fmt"
    "time"
)

var Weekdays = []time.Weekday{
    time.Sunday,
    time.Monday,
    time.Tuesday,
    time.Wednesday,
    time.Thursday,
    time.Friday,
    time.Saturday,
}

func main() {
    for _, day := range Weekdays {
            fmt.Println(day)
    }
}

字符串
为了能够在运行时动态地生成该列表,例如通过反射,链接器必须保留所有包中定义的所有符号,就像Java一样。golang-nuts小组讨论了这一点,关于从包导出的名称和函数,包常量定义的超集。https://groups.google.com/forum/#!topic/golang-nuts/M0ORoEU115o
当且仅当它被程序引用时,语言才有可能在编译时包含用于生成此列表的语法糖。但是,迭代顺序应该是什么呢?如果你的一周从星期一开始,我定义的列表就没有多大帮助;您将必须定义自己的切片,以涵盖从周一到周日的所有日子。

1l5u6lss

1l5u6lss2#

你可以这样做,没有反思。
首先在编译时使用go generate执行Go工具Stringer。这将创建一个文件[filename]_string.go,其中包含枚举值的Map_[structname]_map,该Map将枚举变量名作为字符串引用。这个Map是私有的,所以在包初始化时将其分配给公共Map即可。

var EnumMap map[Enum]string

func init() {
    EnumMap = _Enum_map
}

type Enum uint

//go:generate go run golang.org/x/tools/cmd/stringer -type=Enum

const (
    One Enum = iota
    Two
)

字符串
然后你可以简单地在Map的关键点上循环。

bvk5enib

bvk5enib3#

@Davec的评论很棒。当你有一个以1为增量的计数时,这是完美的。

You could either do a simple loop such as for d := Monday; d <= Sunday; d++ {}

字符串
我有一个以位为单位跳跃的常数(1,2,4,8,16等):

const (
    Approved = 1 << iota
    AlreadyApproved
    NotApproved
    OldTicket
    Unknown
)


我避开了range,做了一个左移1来移动我的常数:

var score Bits
score = Set(score, AlreadyApproved)

for i := Approved; i < Unknown; i = i << 1 {
    fmt.Println(i)
}


输出量:

1
2
4
8
16

wmomyfyw

wmomyfyw4#

最好使用stringer,它可以帮助您使用代码生成器使您的代码库保持最新。不幸的是,stringer并不总是能生成Map。
对于任何有兴趣继续使用go生成器的人,我写了一个小代码生成器,名为enumall。它为每个提供的类型生成一个文件,其中的变量保存给定类型的所有值。
通过向代码中添加代码生成器注解来使用它,如下所示:

//go:generate go run github.com/tomaspavlic/enumall@latest -type=Season

type Season uint8

const (
    Spring Season = 1 << iota
    Summer
    Autumn
    Winter
)

字符串
您可以在此处找到更多信息:https://github.com/tomaspavlic/enumall

gojuced7

gojuced75#

for i := 0; i <= int(Sunday); i++ {
    fmt.Println(DayOfWeek(i))
}

字符串

相关问题