问题 有没有办法迭代常量用作枚举


我试图在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
}

5726
2017-10-17 16:44


起源

首先,所有Go标识符通常都在 MixedCaps,包括常数。你可以做一个简单的循环,如 for d := Monday; d <= Sunday; d++ {} 你明确知道开始/结束值的地方,或者你可以为那些添加别名(例如 firstDay = Monday; lastDay = Sunday)。虽然可以进一步制作可以使用的东西 range IMO绝对不值得。 - Dave C
顺便说一下,已经有了 time.Weekday 来自 time.Sunday 至 time.Saturday。 (当然,你恰好把一周中的几天作为一个任意的例子,这是不重要的)。 - Dave C
戴夫,谢谢你的回复。我纠正了常量的情况。我一般都在寻找枚举,而不仅仅是工作日。 firstDay和lastDay对我来说似乎很有趣。它应该在const列表中还是在变量之外?谢谢! - Jack_125
@DaveC:你的评论可以作为答案 - Vitor De Mario
对于我需要可迭代的枚举,我通常会添加一个虚拟结束标记。以一周中的几天为例,我的代码会有循环 for i := Monday; i < LastDay; i++ {。那样的话,如果地狱冻结了,我需要在本周增加第8天,我只需要推它 LastDay,虚拟结束标记。这是一种常见的语言模式,它没有内置支持迭代枚举,如C,Go等。 - wldsvc


答案:


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

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

当且仅当程序引用该语言时,该语言才有可能在编译时包含用于生成此列表的语法糖。但迭代顺序应该是什么?如果您的周从星期一开始,我定义的列表不是很有用;你必须定义自己的切片,范围从星期一到星期日。


11
2018-03-19 01:35