В Scala Reflection, Как получить универсальный параметр типа конкретного подкласса?
Предполагая, что у меня есть универсальный суперкласс:
class GenericExample[T](
a: String,
b: T
) {
def fn(i: T): T = b
}
и конкретный подкласс:
case class Example(
a: String,
b: Int
) extends GenericExample[Int](a, b)
Я хочу получить параметр типа функции "fn" по отражению scala, поэтому я выбираю и фильтрую по ее элементам:
import ScalaReflection.universe._
val baseType = typeTag[Example]
val member = baseType
.tpe
.member(methodName: TermName)
.asTerm
.alternatives
.map(_.asMethod)
.head
val paramss = member.paramss
val actualTypess: List[List[Type]] = paramss.map {
params =>
params.map {
param =>
param.typeSignature
}
}
Я ожидал, что Scala даст мне правильный результат, которыйList(List(Int))
вместо этого я получил только общийList(List(T))
Пробираясь по документу, я обнаружил, что виновником является typeSignature:
* This method always returns signatures in the most generic way possible, even if the underlying symbol is obtained from an
* instantiation of a generic type.
И это предлагает мне использовать альтернативу:
def typeSignatureIn(site: Type): Type
Однако, поскольку класс Example больше не является универсальным, я не могу получить сайт от typeTag [Example], может кто-нибудь подсказать мне, как получить typeOf [Int] только для typeTag [Example]? Или нет способа сделать это, и я должен вернуться к отражению Java?
Большое спасибо за вашу помощь.
ОБНОВИТЬ: После небольшого теста я обнаружил, что дажеMethodSymbol.returnType не работает, как задумано, следующий код:
member.returnType
также даютT
и это не может быть исправленоasSeenFrom, так как следующий код не меняет результат:
member.returnType.asSeenFrom(baseType.tpe, baseType.tpe.typeSymbol.asClass)