给定一个宏中的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
答案 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(...)
}