generisches Feld des Scala-Makros der generischen Klasse wendet den generischen Typparameter der Klasse nicht an
-
21-12-2019 - |
Frage
Generische Fallklasse
case class GroupResult[T](
group: String,
reduction: Seq[T]
)
Makro-Methode
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => println(m.returnType)
}
c.literalUnit
}
Wenn ich rufe foo[GroupResult[Int]]
Die Ausgabe ist
String
Seq[T]
T wird nicht angewendet?Wie kann ich die Bewerbung bekommen Seq[Int]
?
Lösung
Sie können verwenden typeSignatureIn
so erhalten Sie die Typensignatur einer angegebenen Methode GroupResult[Int]
:
import scala.language.experimental.macros
import scala.reflect.macros.Context
case class GroupResult[T](group: String, reduction: Seq[T])
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => println(m.typeSignatureIn(tpe))
}
c.literalUnit
}
Und dann:
scala> foo[GroupResult[Int]]
=> String
=> Seq[Int]
Wir sind also näher dran, aber jetzt bekommen wir die "Typen" der Accessoren, nicht ihre Rückgabetypen.Wenn wir die Rückgabetypen wollen, können wir die verwenden NullaryMethodType
Extraktor:
def foo[T] = macro fooImpl[T]
def fooImpl[T: c.WeakTypeTag](c: Context) = {
import c.universe._
val tpe = weakTypeOf[T]
tpe.declarations.collect {
case m: MethodSymbol if m.isCaseAccessor => m.typeSignatureIn(tpe) match {
case NullaryMethodType(returnType) => println(returnType)
}
}
c.literalUnit
}
Und dann:
scala> foo[GroupResult[Int]]
String
Seq[Int]
Und wir sind fertig.
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow