如何找出超类的类型参数?

问题描述 投票:0回答:1

我有

trait Foo[T]
class Bar extends Foo[String]

如果我这样做

typeOf[Foo[String]].typeArgs
,我就会得到
String
回来。

但是

typeOf[Bar].baseClasses.flatMap(_.typeArgs)
是空的。

是否不可能找到实际的完整超类型和给定类型? (如果有帮助的话,我实际上正在编写一个宏,因此所有编译时信息应该仍然存在......尽管我认为这实际上并不重要,因为我只在这里查看类型,而不是实际对象)。 ..

scala reflection
1个回答
0
投票

这是可能的,但类型永远不会为您应用 OOTB。您必须采用类型参数和参数,创建一个包含参数符号和对应参数类型的 map/2 列表,然后使用

substituteTypes
或类似的恶作剧。例如。对于子类型,它看起来像这样(我希望超类型是相似的):

  • Scala 2

    // A is a c.WeakTypeTag[A]
    // subtype is a Symbol of A's subtype
    val sEta = subtype.toType.etaExpand
    sEta.finalResultType.substituteTypes(
      sEta.baseType(A.tpe.typeSymbol).typeArgs.map(_.typeSymbol),
      A.tpe.typeArgs
    )
    
  • Scala 3

    // A is a scala.quoted.Type[A]
    // subtype is a Symbol of A's subtype
    subtype.primaryConstructor.paramSymss match {
      // subtype takes type parameters
      case typeParamSymbols :: _ if typeParamSymbols.exists(_.isType) =>
        // we have to figure how subtypes type params map to parent type params
        val appliedTypeByParam: Map[String, TypeRepr] =
          subtype.typeRef
           .baseType(TypeRepr.of[A].typeSymbol)
           .typeArgs
           .map(_.typeSymbol.name)
           .zip(TypeRepr.of[A].typeArgs)
           .toMap
        val typeParamReprs: List[TypeRepr] = typeParamSymbols.map(_.name).map(appliedTypeByParam)
        subtype.typeRef.appliedTo(typeParamReprs)
      // subtype is monomorphic
      case _ =>
        subtype.typeRef
    
© www.soinside.com 2019 - 2024. All rights reserved.