我试图一起使用 Toolbox 和 quasiquote 来做代码生成任务,并在使用从返回的对象的 AST 时遇到 StackOverflowError reify(x).tree
,我的代码如下:
abstract class A[T] {def i: T}
class B(val i: Int) extends A[Int]
object A {
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{universe => ru}
import scala.tools.reflect.ToolBox
val javaSeparator = "$"
val curId = new java.util.concurrent.atomic.AtomicInteger()
protected def freshName(prefix: String): TermName = {
newTermName(s"$prefix$javaSeparator${curId.getAndIncrement}")
}
def main(args: Array[String]) {
val b = new B(2)
calculate(b)
}
def calculate(a: A[_]): Unit = {
val toolBox = runtimeMirror(getClass.getClassLoader).mkToolBox()
val i = freshName("i")
val aTree = reify(a).tree
val tree = q"""
val $i = $aTree.i
println($i)
"""
toolBox.eval(tree)
}
}
当我删除类 A 或使用def calculate(a: B)
的类型参数时,toolBox.eval
成功并按预期工作,即在控制台中打印 2。
我不太明白为什么会发生这种情况,有人可以解释为什么带有类型参数的类定义无法通过评估吗?