Как получить доступ к объектам внутри объекта путем смешивания в признаке с отражением?
Как я могу получить все объекты в объекте с отражением?
Рассмотрим этот код:
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
), с отражением.
Ответы
Ответ 1
Мое решение, основанное на ответе Landei, будет:
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
Нечто похожее сделано в Enumeration.populateNameMap: https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src/library/scala/Enumeration.scala
Ответ 3
Вы должны иметь возможность использовать существующий класс Scala Enumeration
: http://www.scala-lang.org/api/current/scala/Enumeration.html
Кажется, он очень близок к вашему делу!