отражение scala, получить параметр типа суперкласса - PullRequest
0 голосов
/ 25 сентября 2018

Как я могу получить конкретный тип параметров типа суперкласса из подкласса?

Предполагая, что у меня есть общий суперкласс, промежуточный класс и подкласс, как указано ниже:

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 Ответ

0 голосов
/ 26 сентября 2018

Решение на самом деле довольно простое:

def getTypeArgs(t: Type, fromType: Type): List[Type] = {
    t.baseType(fromType.typeSymbol).typeArgs
}

Эта функция проходит все тесты.

...