如何通过在特征中混合使用反射来访问对象中的对象?

时间:2010-11-21 18:48:16

标签: scala reflection enums singleton

如何使用反射获取对象中的所有对象?

考虑以下代码:

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)

trait MyEnum {
  val values: List[MonthDay] = this.getClass.getField("MODULE$")...
  val next: MonthDay = ...
  val previous: MonthDay = ...
}

//Of course the user can create his own 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])或迭代它们({ {1}}或def next: MonthDay不重复几次(这绝对至关重要!)。

我们的想法是def previous: MonthDay访问values对象并找到他们正在扩展的类(MonthDay)的所有单例对象。

3 个答案:

答案 0 :(得分:1)

答案 1 :(得分:1)

我的解决方案基于Landei's answer将是:

trait MyEnum{
   def valsOfType[T:Manifest] = {
      val c=implicitly[Manifest[T]].erasure
      for {m <- getClass.getMethods 
           if m.getParameterTypes.isEmpty && c.isAssignableFrom(m.getReturnType)
      } yield (m.invoke(this).asInstanceOf[T])
   }
}

class MonthDay(month:Int,day:Int)

object MonthDay extends MyEnum {
   //maybe you want to call this "holidays" instead
   lazy val values = valsOfType[MonthDay] 

   val NewYear       = new MonthDay( 1,  1)
   val UnityDay      = new MonthDay(11,  9)
   val SaintNicholas = new MonthDay(12,  6)
   val Christmas     = new MonthDay(12, 24)
}

我不认为你应该再调用这个MyEnum,因为枚举类型意味着一组封闭的值。

(如果枚举值定义为object s)

则不起作用

答案 2 :(得分:0)

您应该可以使用已有的Scala Enumeration课程:http://www.scala-lang.org/api/current/scala/Enumeration.html

它似乎非常接近你的用例!