为什么Scala反射在对象内部工作但不在脚本的顶层?

时间:2014-05-24 09:21:39

标签: scala reflection

此脚本使用反射来查找构造函数的类型签名。它在对象内和顶层包含相同的代码:

// Scala 2.11.1
case class Dirigible(cubicFeet: Int)

object Object {
  val u = scala.reflect.runtime.universe
  val ctor = u.weakTypeOf[Dirigible].decl(u.termNames.CONSTRUCTOR).typeSignature
  def run() {
    println(ctor)
  }
}

Object.run()

val u = scala.reflect.runtime.universe
val ctor = u.weakTypeOf[Dirigible].decl(u.termNames.CONSTRUCTOR).typeSignature
println(ctor)

这是输出:

(cubicFeet: Int)$anon.this.Dirigible
<notype>

为什么顶级代码在Object内的代码有效时会失败?

如果我将println置于顶级def并从顶层调用它,则会发生同样的失败。

如果我通过scala -i refltest.scala在REPL中运行文件,则顶级代码有效。这是可以预料到的,因为REPL将所有东西都放入了一个对象中。我不明白的是,为什么代码内部的代码会影响反射的结果?

1 个答案:

答案 0 :(得分:1)

脚本运行器将您的代码包装在本地匿名类中;您的代码作为初始化程序的一部分运行。

我不知道为什么会破坏反思,但它与this question from a couple of years ago重复。编辑说这个问题已经修复,但我认为它没有用。

作为一种解决方法,将代码包装在一个块中:

locally {
val u = scala.reflect.runtime.universe
val ctor = u.weakTypeOf[Dirigible].decl(u.termNames.CONSTRUCTOR).typeSignature
println(ctor)
}

可能与init命令以及如何编译本地类有关。