1

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在本例中)时做一些哲学上的错误?

4

1 回答 1

2

您可以只接受宇宙作为参数:

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)

请注意,您必须通过实例引用 UniverseMyReflection才能正确获取路径相关类型。

val members: x.u.MemberScope = x.foo[String]

查看此问题以获取更多示例和选项。

于 2013-06-07T19:21:08.157 回答