关于宏:使用Scala准引用提升字符串变量

Lifting string variable using Scala quasiquotes

这是我面临的问题的简化版本,但基本问题仍然存在。
调用宏后,我想动态生成案例类。我能够从宏调用等中检索参数。我遇到的问题是试图在准引用中使用字符串变量。我本质上想拥有以下内容:

1
2
3
4
5
6
7
8
9
10
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
}

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

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

将toGen字符串简单地加上引号,意味着不会生成case类。

我一直在寻找类似的问题,但在任何地方都找不到此示例。如何在准引号中取消对字符串变量的双引号?


Context上定义了一个parse方法。它返回一个Tree,并且因为可以将树用准引号进行插值,所以您可以非常容易地将解析与准引号混合并匹配。
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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宏,但它与宏注释(如您的情况)一样工作。