使用单例对象作为枚举元素的 Scala 枚举,可以对它们进行迭代吗?

6 浏览
0 Comments

使用单例对象作为枚举元素的 Scala 枚举,可以对它们进行迭代吗?

我已经看过关于模拟Java的enum以及Scala的case classesEnumeration的问题,但这似乎是得不偿失。

基本上,我想要一个values方法,它返回DayOfWeek的所有单例对象,而不需要重复写好几次。

这是我的代码应该看起来的样子:

object DayOfWeek extends MyEnum {
  object MONDAY extends DayOfWeek(1)
  object TUESDAY extends DayOfWeek(2)
  object WEDNESDAY extends DayOfWeek(3)
  object THURSDAY extends DayOfWeek(4)
  object FRIDAY extends DayOfWeek(5)
  object SATURDAY extends DayOfWeek(6)
  object SUNDAY extends DayOfWeek(7)
}
class DayOfWeek(ordinal: Int)

方法values应该返回像这样写的一样:

val values = Array(MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
                   FRIDAY, SATURDAY, SUNDAY)

所有事情都应该在MyEnum特质中发生,因此我只需要扩展它以获得功能。

trait MyEnum {
  val values = this.getClass.getField("MODULE$") etc. etc.
}

有什么建议可以完全实现吗?

想法是values访问类并找到其扩展的类的所有单例对象。

编辑:似乎所有建议都没有考虑到用户也可以创建对象,这些对象应该与定义的对象相比较。

我会尝试提供另一个例子,也许更清楚:

object MonthDay extends MyEnum {
  //Some important holidays
  object NewYear       extends MonthDay( 1,  1)
  object UnityDay      extends MonthDay(11,  9)
  object SaintNicholas extends MonthDay(12,  6)
  object Christmas     extends MonthDay(12, 24)
}
class MonthDay(month: Int, day: Int)
//Of course the user can create other MonthDays
val myBirthDay = new MonthDay(month, day)
if(!MonthDay.values.contains(myBirthDay)) "Well, I probably have to work"
else "Great, it is a holiday!"

我想要一个特质(MyEnum),我可以将其混合到持有我的“枚举对象”的对象中,以便返回一个列表(def values: List[MonthDay])或者迭代它们(def next: MonthDaydef previous: MonthDay)。

附注:我根据Ken Bloom的要求为这个问题的第二部分创建了一个新问题

admin 更改状态以发布 2023年5月21日
0
0 Comments

scala.Enumeration已经完全符合您的需求。

我认为您可能对Scala 2.7与Scala 2.8之间的区别感到困惑。您引用的旧问题《在Scala中模拟Java的枚举类型enum》是在Scala 2.7时代写的,虽然我无法测试Scala 2.7的Enumeration具有什么功能,但Scala 2.8的Enumeration确实拥有您正在寻找的所有功能。

您不能使用object SUNDAY extends Value(1)定义值,因为object只有在被调用时才会被初始化。

0
0 Comments

这个怎么样?它要求你为每个新值实际调用一次add方法,但是values返回正确的类型。

abstract class MyEnum{
   type Value     //define me to be the value type for this MyEnum
   private var _values:List[Value] = Nil
   def values = _values    
   protected def add(newValue:Value) = {
      _values = newValue::_values
      newValue
   }
}
object DayOfWeek extends MyEnum{
   class Value(val dayNum:Int)
   val SUNDAY    = add(new Value(1))
   val MONDAY    = add(new Value(2))
   val TUESDAY   = add(new Value(3))
   val WEDNESDAY = add(new Value(4))
   val THURSDAY  = add(new Value(5))
   val FRIDAY    = add(new Value(6))
   val SATURDAY  = add(new Value(7))
}

现在你可以调用

println(DayOfWeek.values map (_.dayNum))

如果你需要具有不同对象上的方法不同定义的单例对象,可以这样创建匿名类:

add(new Value{
      override def dayNum=8
    })

0