Nik*_*kov 8 reflection scala scala-2.10
请考虑以下代码:
object ResponseType extends Enumeration {
val Listing, Album = Value
}
Run Code Online (Sandbox Code Playgroud)
我可以Symbol像这样引用这个对象:
import reflect.runtime.universe._
val s = typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol
Run Code Online (Sandbox Code Playgroud)
现在,有了这个符号,我怎样才能获得实际的ResponseType对象?
Eug*_*ako 13
scala> val moduleClass = typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol
moduleClass: reflect.runtime.universe.Symbol = object ResponseType
scala> val module = moduleClass.owner.typeSignature.member(moduleClass.name.toTermName)
module: reflect.runtime.universe.Symbol = object ResponseType
scala> reflect.runtime.currentMirror.reflectModule(module.asModule).instance
res9: Any = ResponseType
Run Code Online (Sandbox Code Playgroud)
现在,一些解释是有序的,因为这是一个相当模糊的实现细节,我们(还)!无法在公共API中进行抽象.
每个objectScala都会创建一个代表其签名的底层类,内部称为模块类.例如,如果编译编译object C器将生成C$.class.这正是模块类.
请注意,模块类与伴随类不同.说,对于case class C,编译器会生成三个符号:type C,term C和(另一个)type C,其中,所述第一type C表示的C类(其中包含自动生成的拷贝,productPrefix,productArity等)和第二type C表示对象C的签名(其包含自动生成的工厂,提取器等).不会有任何名称冲突,因为模块类不会直接添加到符号表中,只能通过<module>.moduleClass.
所以你从typeOf[ResponseType.Value].asInstanceOf[TypeRef].pre.typeSymbol咒语中得到的是一个代表模块类的符号.API中没有任何功能可以让您从模块类中获取模块符号.在编译器内部肯定有一个,但我们决定不公开这个实现细节,因为它可能很快就会改变.
要访问源模块,您需要owner查看其成员列表,并查找与模块类具有相同名称的对象.这正是做什么的moduleClass.owner.typeSignature.member(moduleClass.name.toTermName).一个小小的警告是,如果在相同的范围内你有一个具有相同名称的方法,那么member将返回一个重载的符号,你需要做类似的事情.member(...).suchThat(_.isModule).
之后,这是一块蛋糕.
编辑.实际上我们正在考虑引入ClassSymbol.module它将返回模块类的源模块符号,否则返回NoSymbol.很可能这最终会在RC1中结束.按照发行说明进行操作
| 归档时间: |
|
| 查看次数: |
1425 次 |
| 最近记录: |