考虑这个例子:
class A
object Macros {
def genA(str: String): A[_] = macro _genA
def _genA(c: Context)(str: c.Expr[String]): c.Expr[A[_]] = {
import c.universe._
c.Expr[A[_]](
reify { new A[Int] }.tree)
}
// somewhere in code
genA("int") // --> new A[Int]
它按预期工作。但是,当我引入通过匹配选择表达式的匹配时,我遇到了问题:
class A
object Macros {
def genA(str: String): A[_] = macro _genA
def _genA(c: Context)(str: c.Expr[String]): c.Expr[A[_]] = {
import c.universe._
c.Expr[A[_]](
Match(
str.tree.duplicate,
List(
CaseDef(Literal(Constant("int")), EmptyTree,
reify { new A[Int] }.tree))))
}
}
// again, somewhere far, far away in the code
genA("int") // it expands to ("int" match { case "int" => new A[Int] })
它编译得很好,但是在宏扩展之后我得到了这个错误:
found : rsf.macros.A[Int]
required: rsf.macros.A[_$1] where type _$1
genA("int")
^
手动输入相同的表达式时,编译得很好:
val a: A[_] = "int" match { case "int" => new A[Int] }
为什么会这样?有没有办法解决它?
编辑:
我现在使用以下解决方法:
class A
object Macros {
def genA(str: String): A[_] = macro _genA
def _genA(c: Context)(str: c.Expr[String]): c.Expr[A[_]] = {
import c.universe._
val mtch = c.Expr[A[_]](
Match(
str.tree.duplicate,
List(
CaseDef(Literal(Constant("int")), EmptyTree,
reify { new A[Int] }.tree))))
reify {
mtch.splice.asInstanceOf[A[_]]
}
}
}
但我觉得每次执行这个宏时,都会有一只小猫死去。或许有什么办法可以让小猫们幸免于难?