通用类的scala宏泛型字段不应用类泛型类型参数

时间:2014-07-29 10:20:53

标签: scala generics macros scala-macros

通用案例类

case class GroupResult[T](
  group: String,
  reduction: Seq[T]
)

宏观方法

 def foo[T] = macro fooImpl[T]

 def fooImpl[T: c.WeakTypeTag](c: Context) = {
    import c.universe._
    val tpe = weakTypeOf[T]
     tpe.declarations.collect {
      case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
    }
    c.literalUnit
  }

当我调用foo[GroupResult[Int]]

输出

String
Seq[T]

不适用?如何获取已应用的Seq[Int]

1 个答案:

答案 0 :(得分:8)

您可以使用typeSignatureIn获取给定GroupResult[Int]的方法的类型签名:

import scala.language.experimental.macros
import scala.reflect.macros.Context

case class GroupResult[T](group: String, reduction: Seq[T])

def foo[T] = macro fooImpl[T]

def fooImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val tpe = weakTypeOf[T]

  tpe.declarations.collect {
    case m: MethodSymbol if m.isCaseAccessor => println(m.typeSignatureIn(tpe))
  }

  c.literalUnit
}

然后:

scala> foo[GroupResult[Int]]
=> String
=> Seq[Int]

所以我们离得更近了,但现在我们得到了访问者的“类型”,而不是它们的返回类型。如果我们想要返回类型,我们可以使用NullaryMethodType提取器:

def foo[T] = macro fooImpl[T]

def fooImpl[T: c.WeakTypeTag](c: Context) = {
  import c.universe._

  val tpe = weakTypeOf[T]

  tpe.declarations.collect {
    case m: MethodSymbol if m.isCaseAccessor => m.typeSignatureIn(tpe) match {
      case NullaryMethodType(returnType) => println(returnType)
    }
  }

  c.literalUnit
}

然后:

scala> foo[GroupResult[Int]]
String
Seq[Int]

我们已经完成了。