如何通过混合特性与反射来访问对象内的对象?
如何使用反射获取对象中的所有对象?如何通过混合特性与反射来访问对象内的对象?
考虑以下代码:
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]
)的列表或者iterate (def next: MonthDay
或def previous: MonthDay
)没有重复自己几次(这是绝对至关重要!)。
想法是values
访问MonthDay
对象,并找到它们正在扩展的类的所有单例对象(MonthDay
)和反射。类似
我的解决方案,基于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不工作)
有东西在Enumeration.populateNameMap完成:https://lampsvn.epfl.ch/trac/scala/browser/scala/tags/R_2_8_1_final/src/library/scala/Enumeration.scala
我已经尝试过这样做,但我不能看清物体/场/方法,如果我看着MonthDay.MODULE $。 – soc 2010-11-21 21:19:01
@soc:他指的是'val methods = getClass.getMethods过滤器(m => m.getParameterTypes.isEmpty && classOf [Value] .isAssignableFrom(m.getReturnType))'它使用普通的Java反射来查找返回正确类型的无参数函数,并假定每个函数都是一个Enumeration值。我想象有一天,当我们有真正的* Scala *反射时,我们将能够判断这些方法是用'object','val'还是'def'创建的(以排除'def's)。 (即使你将对象声明为'object',这个方法也应该可以工作) – 2010-11-23 00:25:36
他还提到了m.invoke(),它将'methods'变成'values'。 – 2010-11-23 00:48:22
您应该能够使用现有的预斯卡拉Enumeration
类:http://www.scala-lang.org/api/current/scala/Enumeration.html
它似乎非常接近你的使用情况!
不是,它不能扩展为提供用户特定的额外实例,因为OP请求 – 2010-11-21 20:26:00
使用'Enumeration',用户不能创建他自己的'MonthDays'。 – 2010-11-23 01:14:00
这看起来非常有趣!这可能是一种值得使用的方法,直到真正的解决方案工作('getClass.getDeclaredClasses',目前不工作,看到这个错误报告:http://lampsvn.epfl.ch/trac/scala/ticket/4023) – soc 2010-11-23 01:24:36
当然,我我可以开一个更好的名字,你有什么想法吗? – soc 2010-11-23 01:25:52
@soc:也许'FindContainedVals' – 2010-11-23 01:27:35