Scala 2.10附带了很棒的反射API。但是,它有两个入口点:运行时Universe和宏上下文Universe。
使用运行时反射时,应导入scala.reflect.runtime.universe
。在宏实现中使用反射时,应该从上下文中导入Universe。
是否可以编写一些适用于这两种环境的代码?如何获得universe
?
考虑这个例子:
class MyReflection(val u: scala.reflect.api.Universe) {
import u._
def foo[T: TypeTag] = implicitly[TypeTag[T]].tpe.members // returns MyReflection.u.MemberScope
}
val x = new MyReflection(scala.reflect.runtime.universe)
val members: scala.reflect.runtime.universe.MemberScope = x.foo[String] // BANG! Compiler error
由于类型不匹配,无法编译。同时,很明显,此示例中的scala.reflect.runtime.universe.MemberScope
和MyReflection.u.MemberScope
共享相同的API。有没有办法抽象不同的宇宙?
或者我是否可能在尝试导出反射工件(在此示例中为MemberScope
)时遇到哲学上的错误?
答案 0 :(得分:2)
您可以接受Universe作为参数:
class MyReflection(val u: scala.reflect.api.Universe) {
import u._
def foo[T : TypeTag] = implicitly[TypeTag[T]].tpe.members
}
val x = new MyReflection(scala.reflect.runtime.universe)
请注意,您必须通过MyReflection
实例引用Universe才能获得与路径相关的类型。
val members: x.u.MemberScope = x.foo[String]
有关更多示例和选项,请查看this question。