0

Verwendung Nehmen wir i eine Datenstruktur haben, die eine parametrierte Art von Daten enthält:scala eine Klasse Argument ein Platzhalter (oder Eingangsgröße)

case class Terminal[A](value: A, name: String ="") 

I eine Terminal[Double] leicht erstellen kann, wenn ich es eine Konstante passieren materialisiert :

val terminal = Terminal(2.0) 

aber ich will es auch input so ein (nicht materialisierte) erhalten können, dass ich den Terminal mehrmals mit verschiedenen Kontexten auswerten kann. Ich kann eine einfache Lösung erreichen, indem value von Namen zu nennen, das heißt

class Terminal[A](value: => A, name: String ="") { 
    def getValue = this.value 
} 

var x = 1.0 

val terminal = new Terminal(x) 

terminal.getValue // 1.0 

x = 100.0 

terminal.getValue // 100.0 

jedoch der Benutzer dieses Programms würde die input mit so etwas wie var input_x = None zu initialisieren hat, was nicht schön ist, und dann seinen Zustand ändern, die in Wende würde mich dazu bringen müssen value in eine Option[A]

Ist dies der beste Weg, um mit dieser Situation umzugehen? Ist kein Designmuster oder Scala-Feature, das ich verwenden könnte?

ich kann auch eine Klasse Input erstellen, um diese kontextabhängigen Eingaben darzustellen, aber dann müsste ich eine Menge Dinge ändern.

+0

Sie scheinen Probleme zu haben, eine bestimmte Lösung für ein Problem anzuwenden. Das Problem ist, dass Sie um Hilfe bei der Implementierung Ihrer Lösung bitten, was mit ziemlicher Sicherheit falsch ist, aber beschreiben Sie niemals das tatsächliche Problem, das Sie lösen möchten. Ich schlage vor, dass Sie einen Schritt zurückgehen und versuchen zu beschreiben, warum (Sie denken) Sie diese "Terminal" -Klasse benötigen und wie Sie sich vorstellen, sie im wirklichen Leben zu benutzen. – Dima

Antwort

1

können Sie unveränderliche Objekte verwenden, wie unten:

scala> case class Terminal[A](value: A, name: String ="") { 
    | def update(newValue: A): Terminal[A] = this.copy(value = newValue) 
    | def getValue: A = this.value 
    | } 
defined class Terminal 

scala> val terminal = Terminal(1.0) 
terminal: Terminal[Double] = Terminal(1.0,) 

scala> val updatedTerminal = terminal.update(100.0) 
updatedTerminal: Terminal[Double] = Terminal(100.0,) 

scala> val oldValue = terminal.getValue 
oldValue: Double = 1.0 

scala> val newValue = updatedTerminal.getValue 
newValue: Double = 100.0 

Die getValue-Methode hier eigentlich überflüssig ist, weil Getter mit case classes frei kommen. Ich hatte es gerade drin, um das Beispiel zu demonstrieren.

scala> oldValue == terminal.value 
res0: Boolean = true 

scala> newValue == updatedTerminal.value 
res1: Boolean = true 

Im allgemeinen Fall Klassen bevorzugen, wenn Sie Objekte erstellen mögen, die nicht veränderbaren Zustand haben (zum Beispiel alle Singleton-Komponenten sind besser ab, als nicht-Fall-Klassen).