我有一个类型resultType的Context.this.type#c#universe#Type.我需要将它与Unit类型相匹配.我试过了
resultType match {
case q"Unit" => ...
}
Run Code Online (Sandbox Code Playgroud)
但我想这Unit只是一个字符串文字,显然不匹配.如何通过quasiqotes匹配类型?
我也尝试过
resultType match {
case TypeRef(ThisType(_), Symbol("scala.Unit"), _) => ...
}
Run Code Online (Sandbox Code Playgroud)
但有一个错误:
[error] pattern type is incompatible with expected type;
[error] found : Symbol
[error] required: Context.this.c.universe.SymbolContextApi
Run Code Online (Sandbox Code Playgroud)
如何以这种方式匹配类型?
Quasiquotes的Scala文档在解释提升时提到了这一点:
也可以结合提升和非提示拼接:
scala> val ints = List(1, 2, 3)
scala> val f123 = q"f(..$ints)"
f123: universe.Tree = f(1, 2, 3)
scala> val intss = List(List(1, 2, 3), List(4, 5), List(6))
scala> val f123456 = q"f(...$intss)"
f123456: universe.Tree = f(1, 2, 3)(4, 5)(6)
Run Code Online (Sandbox Code Playgroud)
具体是代码示例中的提升与非引用拼接的实现?
不幸的是,最直观的方式,
val world = "Earth"
val tree = q"""println("Hello $world")"""
Run Code Online (Sandbox Code Playgroud)
结果是
Error:(16, 36) Don't know how to unquote here
val tree = q"""println("Hello $world")"""
^
Run Code Online (Sandbox Code Playgroud)
因为$在quasiquotes中期望a tree.
val world = "Earth"
val tree = q"""println(${c.literal(s"Hello $world")})"""
Run Code Online (Sandbox Code Playgroud)
工作,但非常难看我得到一个Intellij警告,c.literal不赞成,我应该使用quasiquotes,而不是.
那么......我该怎么做?
UPDATE
回应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")})"""
*/ …Run Code Online (Sandbox Code Playgroud) 使用 Scala2,我可以实现宏并使用tq准引用语法生成类型,例如:
q"""
new Foo {
type Bar = ${tq"(..$params)"}
}
"""
Run Code Online (Sandbox Code Playgroud)
我可以用这种语法做两件事 -
Bar基于params.params。如何使用 Scala 3 实现这一目标?