Отражение scala, получить параметр типа суперкласса
Как я могу получить конкретный тип параметров типа суперкласса из подкласса?
Предполагая, что у меня есть общий суперкласс, промежуточный класс и подкласс, как показано ниже:
class SuperClass[A, B]
class IntClass[A] extends SuperClass[A, Int]
class MyClass extends SuperClass[String, Int]
Я хотел бы функцию "getTypeArgs", которая возвращает параметры типа SuperClass:
val superClassType = typeOf[SuperClass[_, _]]
val superClassOfStringInt = appliedType(superClassType.typeConstructor, typeOf[String], typeOf[Int])
getTypeArgs(superClassOfStringInt, superClassType)
// [TEST1] should return List(String, Int)
getTypeArgs(typeOf[MyClass], superClassType)
// [TEST2] should return List(String, Int)
val intClassOfLong = appliedType(typeOf[IntClass[_]].typeConstructor, typeOf[Long])
getTypeArgs(intClassOfLong, superClassType)
// [TEST3] should return List(Long, Int)
Я пробовал решение В Scala Reflection, Как получить универсальный параметр типа конкретного подкласса?:
def getTypeArgs(t: Type, fromType: Type): List[Type] = {
internal
.thisType(t.dealias.typeSymbol)
.baseType(fromType.typeSymbol.asClass)
.typeArgs
}
Это работает для TEST2, но TEST1 возвращает List(A, B), а TEST3 возвращает List(A, Int).
Я могу исправить TEST1, добавив тест для проверки равенства символов:
def getTypeArgs(t: Type, fromType: Type): List[Type] = {
if (t.erasure.typeSymbol == fromType.typeSymbol)
t.typeArgs
else
internal
.thisType(t.dealias.typeSymbol)
.baseType(fromType.typeSymbol.asClass)
.typeArgs
}
Я не знаю, как заставить TEST3 работать.
1 ответ
Решение
Решение на самом деле довольно простое:
def getTypeArgs(t: Type, fromType: Type): List[Type] = {
t.baseType(fromType.typeSymbol).typeArgs
}
Эта функция проходит все тесты.