Ich versuche, ein Makro zu schreiben, das eine bestimmte Instanz einer Fallklasse in eine Zeichenfolgendarstellung erweitert. Z.B. case class Foo(a: Int); Foo(1)
würde a -> 1
werden.Referenzfeld des Objekts mit Zeichenfolgenwert scala Makro
Also habe ich eine Typenklasse geschrieben, um mir die Feldnamen von einem formlosen LabelledGeneric
namens FieldList
zu geben. Ich gebe die LabelledGeneric- und FieldList-Instanzen an mein Makro weiter, und ich kann das Makro leicht dazu bringen, eine Liste aller Felder zu erzeugen. Ich bin mir jedoch nicht sicher, wie ich die Zeichenfolge, die das Feld darstellt, verwenden kann, um über das Objekt in meinem Makrokörper auf das Feld zuzugreifen. Hier ist der Makrocode:
import FieldList._
import shapeless.{HList, LabelledGeneric}
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
object Foo {
def foo_impl[T, L <: HList](c: blackbox.Context)
(t: c.Expr[T])
(gen: c.Expr[LabelledGeneric.Aux[T, L]],
fl: c.Expr[FieldList[L]]): c.Expr[String] = {
import c.universe._
reify {
val sb = new StringBuilder
val obj = t.splice
val generic = gen.splice
val fieldList = fl.splice
// T.fieldList returns a List[String] of the class' fields.
obj.fieldList(generic, fieldList).foldLeft(sb) { case (builder, next) =>
builder.append(next)
builder.append(" -> ")
builder.append() // How to get the value of obj.$next?
}.toString()
}
}
def foo[T, L <: HList](t: T)(implicit gen: LabelledGeneric.Aux[T, L], fl: FieldList[L]): String = macro foo_impl[T, L]
}
Die Linie, wo ich bin nicht sicher, was zu tun ist, die dritte Linie meiner Falte mit dem Kommentar.
Ich bin sicher, was ich versuche zu tun ist mit schlicht formlos möglich, aber ich versuche, Makros zu lernen. Ich habe Quasiquotes angeschaut, die aussehen, als könnten sie dieses Verhalten unterstützen, aber es sieht so aus, als müsste ich zwischen reify und quasiquotes wählen und AFAICT kann nur auf die Werte eines Expr
innerhalb eines retify Blocks zugreifen (Quasiquotes funktionieren also nicht?) .
Großartig, danke Jasper. Ich werde es gleich versuchen. – rahilb
@rahilb Das hat übrigens bei mir funktioniert, als ich einen Dummy 'FieldList' benutzt habe. –
Danke Jasper: Ich werde deine Antwort akzeptieren, aber mir wurde klar, dass ich tatsächlich die falsche Frage für das gestellt habe, was ich zu tun versuchte! Für meinen Zweck muss ich die formlosen Typen-Tags aus dem Eingabe-Baum extrahieren, da ich zur Kompilierzeit gerne die Feldnamen wissen möchte (ich kämpfe immer noch damit, aber das ist eine andere Geschichte :)). Danke noch einmal. – rahilb