Ich möchte eine Sammlung von Objekten, jedes Objekt ein Begleiter einer anderen Klasse, die alle eine gemeinsame Methode in einer Oberklasse definiert, die beim Durchlaufen der Sammlung mit einem foreach()
aufgerufen werden kann. Ich möchte, dass die Konstruktoren dieser Geschwisterklassen dieselben benannten Parameter und Standardparameterwerte als einander haben. Schließlich möchte ich wiederholten Code minimieren.Scala-Sammlung, deren Elemente Geschwisterinstanzen mithilfe benannter Parameter und Standardwerte erstellen können?
Bis jetzt versuche ich dies mit Fallklassen zu tun, da - wenn es funktioniert - es den gesamten duplizierten Code der Companion-Objekte für jeden Typ eliminieren würde. Das Problem ist, dass, wenn ich alle diese Begleitobjekte in eine Set
setze, wenn ich sie wieder herausnehme, die Standardparameter und Parameternamen verliere. Hier
ist einige Beispiel-Code von dem, was ich beschreibe:
trait MyType {
val param: String
def label = param // all instances of all subclasses have this method
}
case class caseOne(override val param: String = "default") extends MyType
case class caseTwo(override val param: String = "default") extends MyType
object Main extends App {
// I can construct instances using the companion objects' `apply()` method:
val works1 = caseOne(param = "I have been explicitly set").label
// I can construct instances that have the default parameter value
val works2 = caseOne().label
// But what I want to do is something like this:
val set = Set(caseOne, caseTwo)
for {
companion <- set
} {
val fail1 = companion() // Fails to compile--not enough arguments
val fail2 = companion(param = "not default") // Fails also as param has lost its name
val succeeds = companion("nameless param") // this works but not what I want
println(fail1.label + fail2.label) // this line is my goal
}
}
Insbesondere, wenn die Set
nur ein Element hat, dann kompiliert, was auf die abgeleitete Art des Multi-Element-Set
fehlt der Parameter Namen- obwohl sie gleich sind und die Standardwerte. Wenn ich den Set
den richtigen Typparameter gebe, könnte das auch funktionieren. Aber was wäre das für ein Typ? Nicht MyType
da dies der Typ der Companion-Klassen ist eher, dass die Objekte in der Set
.
Ich könnte die Begleitobjekte explizit definieren, aber das ist der wiederholte Code, den ich vermeiden möchte.
Wie kann ich meine Sammlung durchlaufen, Instanzen von MyType
Unterklassen bei jeder Iteration konstruieren, mit Konstruktoren, die meine gewünschten Parameternamen und Standardwerte haben? All dies minimiert den wiederholten Code.
Update: Ursprünglich ist der Beispielcode zeigte caseOne
und caseTwo
wie für param
verschiedene Standardwerte. Das war falsch; sie sind jetzt gleich.
Das sieht so aus, danke! Hinweis: Ich habe im ursprünglichen Beispielcode einen Fehler gemacht: Die beiden Fallklassen sollten (und haben jetzt) denselben Standardwert haben. Weil ich den 'MyTypeHelper' mit einer einzigen' apply() 'Methode verwenden konnte, die den Standardwert definiert und den' default' Parameter aus dem 'MyTypeHelper' Konstruktor entfernt hat. Ich habe auch "Case" von einer Case-Klasse in eine reguläre Klasse geändert und dabei ein Zeichen gespeichert. Du hast mich losgemacht; vielen Dank nochmal! –