使用Scala准引号提升字符串变量



这是我所面临的问题的简化版本,但潜在的问题仍然存在。在调用宏之后,我想动态地生成case类。我能够从宏调用等检索参数。我遇到的问题是试图在准引号内使用字符串变量。我想要有以下内容:

def expand_impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._
    val toGen = "case class Foo()"
    val toReturn = c.Expr[Any](
        q"$toGen"
    )
    toReturn
}

但是,不会生成case类。现在我知道,如果我将toGen更改为q"case类Foo()",它将起作用,但是toGen是一个字符串,我将在其他一些返回字符串的处理后生成,所以我不能这样做。像这样编译它并手动查看toReturn的值,我得到以下结果:

Expr[Any]("case class Foo()")

字符串toGen只是沿着引号粘贴进去,这意味着不会生成case类。

我找过类似的问题,但找不到这个例子。如何取消准引号内字符串变量的双引号?

Context上定义了一个parse方法。它返回一个Tree,因为树可以在准引号中插入,所以可以很容易地混合匹配解析和准引号。通过例子:

scala> :paste
// Entering paste mode (ctrl-D to finish)
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
def test_impl(c: Context)(): c.Tree = {
  import c.universe._
  val tree = c.parse("""println(2)""")
  q"println(1); $tree; println(3)"
}
def test(): Unit = macro test_impl
// Exiting paste mode, now interpreting.
import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
test_impl: (c: scala.reflect.macros.whitebox.Context)()c.Tree
defined term macro test: ()Unit
scala> test()
1
2
3

在这个例子中,我定义了一个def宏,但它应该与宏注释一样好(就像你的情况一样)。

相关内容

  • 没有找到相关文章

最新更新