使用Singleton对象作为枚举元素的Scala枚举以及迭代它们的可能性?

soc*_*soc 9 java reflection enums scala

我已经看过关于模拟Javaenum案例类与EnumerationScala问题,但似乎太多的努力,太少的好处.

基本上我想有一个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)
Run Code Online (Sandbox Code Playgroud)

该方法values应返回类似如下所示的内容:

val values = Array(MONDAY, TUESDAY, WEDNESDAY, THURSDAY,
                   FRIDAY, SATURDAY, SUNDAY)
Run Code Online (Sandbox Code Playgroud)

一切都应该在MyEnum特质中发生,所以我只需要扩展它来获得功能.

trait MyEnum {
  val values = this.getClass.getField("MODULE$") etc. etc.
}
Run Code Online (Sandbox Code Playgroud)

有什么建议可以做到这一点吗?这个想法是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!"
Run Code Online (Sandbox Code Playgroud)

我想要一个trait(MyEnum),我可以将其混合到持有我的"枚举对象"的对象中,并使用方法返回它们的列表(def values: List[MonthDay])或迭代它们(def next: MonthDaydef previous: MonthDay).

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

Ken*_*oom 5

这个怎么样?它要求您实际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))
}
Run Code Online (Sandbox Code Playgroud)

你现在可以打电话了

println(DayOfWeek.values map (_.dayNum))
Run Code Online (Sandbox Code Playgroud)

如果您需要在不同对象上具有不同方法定义的单例对象,则可以创建如下的匿名类:

add(new Value{
      override def dayNum=8
    })
Run Code Online (Sandbox Code Playgroud)

  • 正如一个侧面来看,要使用类型的``var`列表[超值]`内部,而不是'val`类型的数组`[超值]`,因为你要值列表返回给用户是完全不变的. (2认同)