scala之使用 Scala quasiquotes 提升字符串变量

arxive 阅读:16 2025-01-19 22:14:33 评论:0

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

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 的值,我得到以下信息:
Expr[Any]("case class Foo()") 

字符串 toGen 被简单地粘贴在引号中,这意味着不会生成案例类。

我一直在寻找类似的问题,但在任何地方都找不到这个例子。如何在 quasiquotes 中取消引用字符串变量的双引号?

请您参考如下方法:

有一个parseContext 上定义的方法.它返回一个 Tree ,并且因为树可以在 quasiquotes 中插入,所以您可以很容易地将解析与 quasiquoting 混合和匹配。
举例:

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 宏,但它应该与宏注释一起工作(就像你的情况一样)。


标签:Scala
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

关注我们

一个IT知识分享的公众号