为什么从宏返回一个匹配给我类型错误?

时间:2013-07-02 06:29:25

标签: scala macros scala-2.10

考虑这个例子:

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[_]]
    }
  }
}

但是我觉得每次这个宏执行时,小猫都会死掉。也许有一些方法可以放过小猫?

0 个答案:

没有答案