Scala宏:查找Option的封闭类型

时间:2014-01-05 18:18:07

标签: scala reflection macros scala-macros

给定一个宏中的Option[T],我试图找到所附的类型T,这样就可以得到类似

的内容
import scala.language.experimental.macros
import scala.reflect.macros.Context

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

  val tpe = weakTypeOf[T]
  val innerType = tpe.typeSymbol.asType.typeParams.head.name.decoded
  c.Expr[String] { q" {$innerType} " }
}

def innerType[T] = macro innerTypeImpl[T]

调用innerType[Option[Int]]将返回"Int"(而现在它返回"A",这对应于Option定义中使用的类型参数)

T可能不是Option(计划是使用tpe.typeSymbol.name.decoded == "Option"来确定T是否为Option),所以我不是能够在T

上放置任何边界

1 个答案:

答案 0 :(得分:4)

我猜你想要这样的东西:

val innerType = weakTypeOf[T] match {
  case r: TypeRef => r.args.head
  case _ => c.abort(c.enclosingPosition, "call this method with known type parameter only.")
}

请注意,WeakTypeTag可能不是TypeRef

此方法将在None.type上失败。要使其适用于子类型(例如None.type),您应该使用这样的方法baseType

val innerType = weakTypeOf[T].baseType(typeOf[Option[_]].typeSymbol) match {
  case TypeRef(_, _, targ :: Nil) => targ
  case NoType => c.abort(...)
}