我正在尝试在以下宏中使用 freshName 作为参数名称:
我。
def test: Unit = macro implTst
def implTst(c: blackbox.Context): c.Expr[Unit] = {
import c.universe._
def withImplicitsM(exprs: List[c.Tree], expr: c.Tree): c.Tree =
exprs match {
case Nil =>
expr
case head :: tail =>
//error here
q"""$head.flatMap(implicit ${c.freshName()} => ${withImplicitsM(tail, expr)})"""
}
val exprsIo = List(q"cats.effect.IO.apply(1)", q"cats.effect.IO.apply(2)")
val resultTree = q"""println(${withImplicitsM(exprsIo, q"cats.effect.IO.apply(3)")}.unsafeRunSync())"""
c.Expr[Unit](resultTree)
}
它抛出编译错误:
[error] Main.scala:25:9: exception during macro expansion:
[error] java.lang.IllegalArgumentException: "fresh$macro$2" is not valid representation of a parameter, consider reformatting it into q"val $name: $T = $default" shape
二、
用硬编码标识符替换新名称使其工作:
def test: Unit = macro implTst
def implTst(c: blackbox.Context): c.Expr[Unit] = {
import c.universe._
def withImplicitsM(exprs: List[c.Tree], expr: c.Tree): c.Tree =
exprs match {
case Nil =>
expr
case head :: tail =>
q"""$head.flatMap(implicit i => ${withImplicitsM(tail, expr)})"""
}
val exprsIo = List(q"cats.effect.IO.apply(1)", q"cats.effect.IO.apply(2)")
val resultTree = q"""println(${withImplicitsM(exprsIo, q"cats.effect.IO.apply(3)")}.unsafeRunSync())"""
c.Expr[Unit](resultTree)
}
有没有办法在implicit ${c.freshName()}
不明确指定参数类型的情况下使用?