Ich möchte irgendwie zur Kompilierzeit den Namen eines Feldes einer Fallklasse in einem val bekommen (möglicherweise eine Singleton-typisierte Zeichenkette oder ein Symbol?).Wie erhält man den Namen eines Fallklassenfelds als String/Symbol zum Zeitpunkt der Kompilierung mit formlosem?
Etwas wie folgt aus:
import shapeless._
case class MyClass(field1: String, field2: Int)
val field1Lens = lens[MyClass] >> 'field1
// val name = field1Lens.name // it should be "field1", aka 'field1.name
Ich muss jede Technik nicht unbedingt Linsen verwenden, die funktioniert, ist in Ordnung (etwas mit LabelledGeneric
?). Ich möchte etwas haben, wo ich den Namen des Fallklassenfelds bekommen kann, ohne es separat zu spezifizieren. Auf diese Weise, wenn ich den Namen des field1
Mitglied in der Klasse umgestalten, ändert sich name
entsprechend.
Natürlich ist die folgende nicht funktioniert, weil das Makro bei der Kompilierung nicht weiß, den Namen des Symbols:
val name = 'field1
val field1Lens = lens[MyClass] >> name // can't possibly work
ich lens[MyClass] >> name.narrow
versucht, aber es funktioniert nicht, entweder
Diese ist das, was ich derzeit tue, und natürlich mag ich es nicht:
// If I change the name of the field, compilation fails
// and I'm forced to check this line of code so I can change the string in the line below
protected val fieldNameCheck = lens[X].someField
val someField = "someField"
edit: Ok, ich einen Blick auf gabriele ‚s Frage gab, und von 0 mitIch kann einen HList bekommen, der die (markierten) Schlüssel des Datensatzes enthält. Was ich jedoch brauche, ist ein bestimmtes Feld zu bekommen, nicht eine Liste, die alle enthält.
Ich versuche select
zu verwenden, um einen bestimmten Schlüssel zu bekommen, aber ich habe nicht so weit
import shapeless._
import shapeless.syntax.singleton._
import shapeless.ops.record._
case class Foo(bar: String, baz: Boolean)
val labl = LabelledGeneric[Foo]
val keys = Keys[labl.Repr].apply
// the following doesn't work
// val bar = 'bar.narrow
// keys.select[bar.type]
// keys.get('bar)
Mögliche Duplikate von [Label-Werte aus einer LabelledGeneric-Instanz extrahieren] (http://stackoverflow.com/questions/27434302/extract-label-values-from-a-bellledgeeric-instance) –
Ich glaube nicht, dass ich verstehe Die Motivation - es klingt so, als ob Sie die wörtliche "Bar" an einer Stelle in Ihrem Code schreiben möchten, damit Sie sie nicht an einem anderen Ort schreiben müssen, und ich bin mir nicht sicher, wie das beim Refactoring hilft. Wenn Sie Bedenken haben, dass sich die Mitgliedsnamen ändern, sind die positionellen Selektoren möglicherweise die bessere Wahl. –
Lange Rede, kurzer Sinn: Serialisierungsbibliotheken.Ich möchte nicht gezwungen werden, benutzerdefinierte Serialisierer zu schreiben, um das zu tun, was die Bibliotheken bereits tun (indem ich JSON-Objekte mit Feldnamen als Schlüssel usw. schreibe), nur weil ich den Namen des Feldes an einer anderen Stelle haben muss (zB bei teilweiser Aktualisierung) auf elasticsearch). Ich schreibe die Literalleiste nur einmal, aber wenn sich die Fallklasse ändert, wird der Code trotzdem kompiliert. Ich würde eine Menge Tests brauchen, nur um sicher zu gehen, dass für jeden "Balken", den ich brauche, ein '(bar: T)' Case-Klasse-Param genau das selbe ist: eins für jedes Feld jeder Klasse. –