2016-03-22 13 views
1

Ich habe normale Scala-Klasse Ich möchte umwandeln, um eine unveränderliche Fallklasse zu werden. Da ich die Klasse brauche, um sich in Set Operationen gut zu benehmen, möchte ich, dass alle Scala-Compiler automatisch Methoden generiert, die in einer Fallklasse bereitgestellt werden. IOW, ich möchte vermeiden, diese verschiedenen Methoden schreiben zu müssen; equals, hashCode, toString usw., da dies sehr fehleranfällig ist. Und ich muss das für eine ganze Reihe von Klassen tun, also brauche ich eine allgemeine Lösung, nicht nur eine spezifische Lösung, eine anomale schnelle Lösung oder einen Hack.Ich brauche ein spezifisches Beispiel, wie man einen lokalen Parameter im primären Konstruktor einer unveränderlichen _case_ Klasse definiert

Hier ist die Klasse, mit denen ich arbeite:

class Node(val identity: String, childrenArg: List[Node], customNodeArg: CustomNode) { 
    val children: List[Node] = childrenArg 
    val customNode: CustomNode = customNodeArg 
} 

Wie Sie sehen können, hat der Konstruktor der Klasse drei Parameter. Die erste, identity, ist eine schreibgeschützte Eigenschaft. Die verbleibenden zwei, childrenArg und customNodeArg, sind nur eine normale Methode Parameter; d.h. sie sind nur während der Konstruktion der Instanz vorhanden und verschwinden dann vollständig aus der Klasseninstanz (wenn nicht anders erfasst) nach der Ausführung des Klassenkonstruktors.

Mein erster naiver Versuch, dies zu einer unveränderlichen Fall Klasse zu konvertieren dies wurde (Entfernen von nur val aus dem ersten Parameter):

class Node(identity: String, childrenArg: List[Node], customNodeArg: CustomNode) { 
    val children: List[Node] = childrenArg 
    val customNode: CustomNode = customNodeArg 
} 

Dies ist jedoch in dem unerwünschten Effekt resultierte sowohl die childrenArg und customNodeArg Parameter jetzt erhöht werden, um (schreibgeschützte) Eigenschaften zu werden (im Gegensatz dazu, sie als normale Methodenparameter zu belassen). Und dies hatte den weiteren unerwünschten Effekt, sie in die vom Compiler erzeugten Implementierungen equals und hashCode aufzunehmen.

Wie kann ich die unveränderlichen Fall Klasse Konstruktor Parameter markieren childrenArg und customNodeArg so dass identity ist die einzige schreibgeschützte Eigenschaft des Falles Klasse?

Alle Hinweise dazu; Antworten, Website-Diskussions-Links usw. werden sehr geschätzt.

+0

Dies ist speziell über die Scala _case_ Klasse, nicht die allgemeine Scala Klasse . IOW, das ist KEIN Duplikat dieser anderen StackOverflow Fragen: http://stackoverflow.com/q/1889454/501113 – chaotic3quilibrium

Antwort

1

Eine zweite Parameterliste scheint den Trick zu tun:

scala> trait CustomNode 
defined trait CustomNode 

scala> case class Node(identity: String)(childrenArg: List[Node], customNodeArg: CustomNode) 
defined class Node 

scala> val n = Node("id")(Nil, null) 
n: Node = Node(id) 

scala> n.identity 
res0: String = id 

scala> n.getClass.getDeclaredFields.map(_.getName) 
res1: Array[String] = Array(identity) 
+0

Das ist genau die Art von Lösung, die ich suchte! Tysvm! Scala ist SO flexibel, manchmal kann ich keine Lösung sehen. Ich wusste von zusätzlichen Argumentlisten. Ich hatte sie noch nie gesehen oder gedacht. Genial! – chaotic3quilibrium

+0

Ich habe Ihre Lösung verwendet, um eine andere StackOverflow-Frage zu beantworten, die sich auf das Auffinden von Zyklen in einem gerichteten Diagramm bezieht.Ich habe es in der abstrakten Fallklasse am Ende der Antwort verwendet: http://stackoverflow.com/a/36144158/501113 – chaotic3quilibrium

0

Fallklassenparameter sind standardmäßig Vals, Sie können sie jedoch auf vars setzen.

case class Node(identity: String, var childrenArg: List[Node], var customNodeArg: CustomNode) 

machen sie Vars gibt Ihnen Getter und Setter automatisch

+0

Ich denke nicht, dass dies mein Problem nicht sowohl als 'childrenArg' als auch' customNodeArg' löst Parameter sind immer noch Eigenschaften; d. h. sie sind in den vom Compiler erzeugten "equals" - und "hashCode" -Funktionsimplementierungen enthalten. Und während es impliziert wurde (und ich habe meine Frage bearbeitet, um es jetzt explizit zu machen), muss die Fallklasse unveränderlich sein. Und das Vorhandensein von irgendwelchen "var" -Parametern macht die Fallklasse veränderbar. – chaotic3quilibrium