generisches Feld des Scala-Makros der generischen Klasse wendet den generischen Typparameter der Klasse nicht an

StackOverflow https://stackoverflow.com//questions/25013047

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] ?

War es hilfreich?

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
scroll top