Я пытался использовать панель инструментов и quasiquote вместе, чтобы выполнять задачи генерации кода, и столкнулись с StackOverflowError при использовании AST объекта вернулся из reify(x).tree
, мой код выглядит следующим образом:AST unquoting используя quasiquotes и дерево вернулся из материализовать
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 в консоли.
Я не совсем понимаю, почему это происходит, может кто-нибудь объяснить, почему определение класса с параметрами типа не дает оценку?
Похож на ошибку. Хотя сначала я хотел бы спросить, чего вы хотели достичь, выполнив 'reify (a) .tree'. Какой результат вы ожидаете? –
@EugeneBurmako, приведенный выше код был просто для того, чтобы показать неудачу, с которой я столкнулся. В моем реальном проекте, поскольку A имеет много подклассов с разным типом массива, я хочу манипулировать ими во всех вычислениях, в то же время избегая боковых и ненужных издержек из-за полинома. reify (a) .tree было просто использовать параметр в AST, который я могу рассмотреть. Есть ли более эффективные способы использования аргумента непосредственно в AST? Спасибо. –
Итак, когда вы пишете 'reify (a) .tree', вы хотите получить' Ident (TermName («a»)), который сохраняет ссылку на значение времени выполнения аргумента 'a', переданного текущему вызову метода, правильно? –