Gibt es objektive Vorteile, oder ist es nur persönliche Präferenz?
Ich denke, es gibt eine dünne Linie zwischen objektiven Vorteilen und persönlichen Vorlieben. Du kannst keinen glauben machen, dass es eine absolute Wahrheit gibt. Der größte Vorteil, den man aus der Verwendung der monadischen Natur von Scala-Konstrukten erhält, ist Zusammensetzung. Die Möglichkeit, Operationen miteinander zu verketten, ohne sich um den internen Wert "Sorgen machen" zu müssen, ist nicht nur mit Option[T]
, sondern auch mit Future[T]
, Either[A, B]
und dazwischen und zurück (siehe auch Monad Transformers) möglich.
Lassen Sie uns versuchen zu sehen, wie die Verwendung vordefinierter Methoden auf Option[T]
kann mit Kontrollfluss helfen. Betrachten Sie zum Beispiel einen Fall, in dem Sie eine Option[Int]
haben, die Sie nur dann multiplizieren möchten, wenn sie größer als ein Wert ist, andernfalls geben Sie -1 zurück. Im Imperativ Ansatz, erhalten wir:
val option: Option[Int] = generateOptionValue
var res: Int = if (option.isDefined) {
val value = option.get
if (value > 40) value * 2 else -1
} else -1
Sammlungen Stil Methode auf Option
Verwendung wäre ein Äquivalent wie folgt aussehen:
val result: Int = option
.filter(_ > 40)
.map(_ * 2)
.getOrElse(-1)
Werfen wir nun einen Fall für Komposition betrachten. Nehmen wir an, wir haben eine Operation, die eine Ausnahme auslösen könnte. Zusätzlich kann diese Operation einen Wert ergeben oder nicht. Wenn es einen Wert zurückgibt, möchten wir eine Datenbank mit diesem Wert abfragen, andernfalls geben wir eine leere Zeichenfolge zurück.
Ein Blick auf die zwingende Ansatz mit einem try-catch
Block:
var result: String = _
try {
val maybeResult = dangerousMethod()
if (maybeResult.isDefined) {
result = queryDatabase(maybeResult.get)
} else result = ""
}
catch {
case NonFatal(e) => result = ""
}
Nun wollen wir zusammen mit scala.util.Try
betrachten mit einem Option[String]
und Komponieren beide zusammen:
val result: String = Try(dangerousMethod())
.toOption
.flatten
.map(queryDatabase)
.getOrElse("")
Ich denke, das kocht schließlich nach unten zu welches Ihnen helfen kann, klaren Kontrollfluß Ihrer Betriebe zu verursachen. Gewöhnen Sie sich an die Arbeit mit Option[T].map
statt Option[T].get
wird Ihren Code sicherer machen.
Zum Schluss glaube ich nicht, dass es eine einzige Wahrheit gibt. Ich glaube, dass die Komposition zu einem schönen, lesbaren Nebeneffekt bei der Zurückstellung von sicherem Code führen kann und ich bin dafür. Ich denke, der beste Weg, anderen Menschen zu zeigen, was du fühlst, ist, ihnen Beispiele zu geben, wie wir es gerade gesehen haben, und ihnen die Kraft zu geben, die sie mit diesen Werkzeugsets nutzen können.
Der Vorteil ist aus der Perspektive der funktionalen Programmierung. Sie können innerhalb des monadischen Wrappers bleiben und Ihren Fluss verketten. Dies mag im Falle von "Option" ähnlich erscheinen, aber wenn Sie an etwas wie "Zukunft" denken, wird "isEmpty" Ihnen überhaupt nicht helfen. –
Betrachte auch die 'fold' Variante:' someOption.fold (foo) (value => ???) '. Und die 'match'-Variante:' someOption match {case Some (value) => ??? Fall None => foo} ' – Kolmar
Es gibt auch eine dritte Variante, die ich persönlich bevorzuge. 'someOption match {case Some (Objekt) => ... case None => ...}' – mgosk