Как получить доступ к объектам внутри объекта, смешивая черту с отражением? - PullRequest
4 голосов
/ 21 ноября 2010

Как я могу получить все объекты внутри объекта с отражением?

Рассмотрим этот код:

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]) или перебрать их (def next: MonthDay или def previous: MonthDay) , не повторяя себя несколько раз (этоабсолютно необходимо!).

Идея состоит в том, что values обращается к объекту MonthDay и находит все одноэлементные объекты класса, который они расширяют (MonthDay) с отражением.

Ответы [ 3 ]

1 голос
/ 23 ноября 2010

Мое решение, основанное на ответе Ландея будет:

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 с)

1 голос
/ 21 ноября 2010

Нечто подобное делается в Enumeration.populateNameMap: https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src/library/scala/Enumeration.scala

0 голосов
/ 21 ноября 2010

Вы можете использовать ранее существующий класс Scala Enumeration: http://www.scala -lang.org / api / current / scala / Enumeration.html

Кажется, он очень близок к вашему сценарию использования!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...