使用 Scala quasiquotes 提升字符串变量
Lifting string variable using Scala quasiquotes
这是我面临的问题的简化版本,但根本问题仍然存在。
调用宏后,我想动态生成 case classes。我能够从宏调用等中检索参数。我遇到的问题是尝试在准引号内使用字符串变量。我基本上想要以下内容:
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
}
但是,案例class没有生成。现在我知道,如果我将 toGen 更改为 q"case class Foo()" 它会起作用,但是 toGen 是一个字符串,我将在经过一些其他处理后生成 returns 一个字符串,所以我不能那样做。
像这样编译它并手动查看 toReturn 的值我得到以下内容:
Expr[Any]("case class Foo()")
字符串 toGen 只是粘贴在引号中,这意味着不会生成大小写 class。
我已经寻找过类似的问题,但在任何地方都找不到这个例子。如何在准引号内取消引用字符串变量的双引号?
在 Context
上定义了一个 parse
方法。它 returns 一个 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 宏,但它应该与宏注释一起工作(如您的情况)。
这是我面临的问题的简化版本,但根本问题仍然存在。 调用宏后,我想动态生成 case classes。我能够从宏调用等中检索参数。我遇到的问题是尝试在准引号内使用字符串变量。我基本上想要以下内容:
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
}
但是,案例class没有生成。现在我知道,如果我将 toGen 更改为 q"case class Foo()" 它会起作用,但是 toGen 是一个字符串,我将在经过一些其他处理后生成 returns 一个字符串,所以我不能那样做。 像这样编译它并手动查看 toReturn 的值我得到以下内容:
Expr[Any]("case class Foo()")
字符串 toGen 只是粘贴在引号中,这意味着不会生成大小写 class。
我已经寻找过类似的问题,但在任何地方都找不到这个例子。如何在准引号内取消引用字符串变量的双引号?
在 Context
上定义了一个 parse
方法。它 returns 一个 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 宏,但它应该与宏注释一起工作(如您的情况)。