Unter der Annahme, dass ich eine generische Oberklasse:In Scala Reflection, Wie generischer Typ Parameter einer konkreten Unterklasse erhalten?
class GenericExample[T](
a: String,
b: T
) {
def fn(i: T): T = b
}
und eine konkrete Unterklasse:
case class Example(
a: String,
b: Int
) extends GenericExample[Int](a, b)
Ich mag die Typ-Parameter-Funktion „fn“ durch scala Reflexion erhalten, so dass ich wähle und Filter ihre Mitglieder durch:
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
}
}
ich scala erwartete mich das richtige Ergebnis zu erhalten, das List(List(Int))
ist, sondern ich nur g ot der Gattungs List(List(T))
durch das Dokument Knirschen ich, dass typeSignature gefunden ist der Täter:
* 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.
Und es schlägt mir die Alternative zu verwenden:
def typeSignatureIn(site: Type): Type
Da jedoch Klasse Beispiel nicht ist länger generisch, es gibt keine Möglichkeit, dass ich eine Site von typeTag [Beispiel] bekomme, kann mir jemand vorschlagen, wie typeOf [Int] nur typeTag [Example] erhalten wird? Oder gibt es keine Möglichkeit dies zu tun und ich muss auf Java-Reflektion zurückgreifen?
Vielen Dank für Ihre Hilfe.
UPDATE: Nach einigen schnellen Test fand ich, dass auch MethodSymbol.returnType nicht wie vorgesehen funktioniert, den folgenden Code:
member.returnType
auch T
ergeben, annd es kann nicht korrigiert werden von asSeenFrom, wie der folgende Code das Ergebnis nicht ändern:
member.returnType.asSeenFrom(baseType.tpe, baseType.tpe.typeSymbol.asClass)
Noch bevor Sie tatsächlich Ihre Frage gelesen haben. Während meiner gesamten Erfahrung mit Scala besteht eines der Kernkonzepte darin, so viel wie möglich an den Compiler zu delegieren. Reflexion ist also nicht eines der Dinge, die du in Scala machen würdest. Sie können jedoch Makros oder Kontextgrenzen (Manifeste und ClassManifests) verwenden. – caeus
Wird Manifest veraltet? Und ClassManifest in ClassTag umbenannt? Ich hoffe, ich kann den gelöschten ClassTag zumindest aus der Methode herausholen, aber es ist immer noch nicht möglich. – tribbloid