不幸的是,最直观的方式,
val world = "Earth"
val tree = q"""println("Hello $world")"""
结果
Error:(16, 36) Don't know how to unquote here
val tree = q"""println("Hello $world")"""
^
因为quasiquotes中的$
需要tree
。
val world = "Earth"
val tree = q"""println(${c.literal(s"Hello $world")})"""
有效但非常难看我得到了一个Intellij警告,c.literal
已弃用,我应该使用quasiquotes代替。
所以...我该怎么做?
更新
回应flavian的评论:
import scala.language.experimental.macros
import scala.reflect.macros._
object TestMacros {
def doTest() = macro impl
def impl(c: blackbox.Context)(): c.Expr[Unit] = {
import c.universe._ //access to AST classes
/*
val world = "Earth"
val tree = q"""println(${c.literal(s"Hello $world")})"""
*/
val world = TermName("Earth")
val tree = q"""println("Hello $world")"""
tree match {
case q"""println("Hello Earth")""" => println("succeeded")
case _ => c.abort(c.enclosingPosition, s"huh? was: $tree")
}
c.Expr(tree) //wrap tree and tag with its type
}
}
给出
Error:(18, 40) Don't know how to unquote here
val tree = q"""println("Hello $world")"""
^
答案 0 :(得分:7)
您需要一个call
或者是编译原语的东西。
真正的问题是你正在混合插补器而没有意识到。 hello world中的插值器实际上是一个字符串插值器,而不是像你建议的那样擅长取消引用树的quasiquote。
这是一种解决方法:
TermName