scala 如何找到一个超类的类型args?

bxgwgixi  于 2023-10-18  发布在  Scala
关注(0)|答案(1)|浏览(112)

我有

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

如果我做typeOf[Foo[String]].typeArgs,我得到String
但是typeOf[Bar].baseClasses.flatMap(_.typeArgs)是空的。
是否不可能找到实际的完整超类型和给定类型?(如果有帮助的话,我实际上是在写一个宏,所以所有的编译时信息都应该在那里。虽然我不认为这实际上有什么关系,因为我在这里只看类型,而不是实际的对象).

a11xaf1n

a11xaf1n1#

这是可能的,但类型永远不会应用于您的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
)
  • 斯卡拉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

当然,在像GADT这样的情况下,您最好编写一组测试以确保没有遗漏任何内容,因为使用反射(甚至是编译时),您认为理所当然的许多事情都消失了。

相关问题