Warum ist es besser als für Scala -Optionen zu bekommen?
-
26-10-2019 - |
Frage
Warum verwenden foreach
, map
, flatMap
usw. werden als besser angesehen als benutzt get
Für Scala -Optionen? Wenn ich benutzeisEmpty
Ich kann anrufen get
sicher.
Lösung
Nun, es kommt irgendwie zurück, um "sagen, nicht fragen". Betrachten Sie diese beiden Zeilen:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
Im ersten Fall schauen Sie hinein opt
Und dann reagieren Sie je nach dem, was Sie sehen. Im zweiten Fall erzählen Sie es nur opt
Was Sie tun wollen, und lassen Sie es damit umgehen.
Der erste Fall weiß zu viel darüber Option
, Replicates Logic intern, ist zerbrechlich und fehlerhaft anfällig (es kann zu Fehlern von Laufzeitfehlern führen, anstatt zu Kompilierungsfehlern, falls falsch geschrieben).
Hinzu kommt, es ist nicht komponierbar. Wenn Sie drei Optionen haben, kümmert sich eine einzige für das Verständnis darum:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
Mit if
, Die Dinge werden schnell unordentlich.
Andere Tipps
Ein schöner Grund zu verwenden foreach
Parsen etwas mit verschachtelten Optionen. Wenn Sie so etwas haben wie
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
Die Konsole druckt 1
. Wenn Sie dies auf einen Fall erweitern, in dem Sie eine Klasse haben, die optional einen Verweis auf etwas speichert, das wiederum eine andere Referenz speichert, können Sie eine riesige "Pyramide" von keiner/einige Überprüfung vermeiden.
Es gibt bereits hervorragende Antworten auf die tatsächliche Frage, aber für mehr Option
-foo du solltest auf jeden Fall auschecken Tony Morris 'Option Cheat Sheet.
Der Grund, warum es nützlicher ist, Dinge wie anzuwenden wie map
, foreach
, und flatMap
direkt zum Option
anstatt zu verwenden get
Und dann die Funktion durchführen ist, dass sie bei beiden funktioniert Some
oder None
Und Sie müssen keine speziellen Schecks durchführen, um sicherzustellen, dass der Wert vorhanden ist.
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
Das Ergebnis für y
Hier ist ein Option[Int]
, was wünschenswert ist, wenn wenn x
ist dann optional, dann y
könnte auch unbestimmt sein. Seit get
funktioniert nicht weiter None
, Sie müssten eine Menge zusätzlicher Arbeit erledigen, um sicherzustellen, dass Sie keine Fehler erhalten haben. zusätzliche Arbeit, die für Sie von Ihnen erledigt ist map
.
Einfach ausgedrückt:
Wenn Sie etwas tun müssen (eine Prozedur, wenn Sie den Rückgabewert jedes Aufrufs nicht erfassen müssen) nur, wenn die Option definiert ist (dh ist a
Some
): verwendenforeach
(Wenn Sie sich für die Ergebnisse jeder Aufruf interessieren, verwenden Siemap
)Wenn Sie etwas tun müssen, wenn die Option definiert ist und etwas anderes, wenn dies nicht der Fall ist: Verwenden Sie
isDefined
in einer IF -AussageWenn Sie den Wert benötigen, wenn die Option a ist
Some
, oder ein Standardwert, wenn es a istNone
: verwendengetOrElse
Versuch, unsere Operationen mit durchzuführen get
ist ein wesentlicherer Stil, in dem Sie telen müssen Was zu tun und wie zu tun ist . Mit anderen Worten, wir diktieren Dinge und graben mehr in die Options
Interna. Wohingegen map,flatmap
sind funktioniertere Art, Dinge zu tun, wo wir sagen Was zu tun ist, aber nicht wie es zu tun ist.