Angenommen, ich habe eine Methode session.get(str: String): String
aber Sie wissen nicht, ob es Ihnen einen String oder eine Null zurückgibt, weil es von Java kommt.
Gibt es eine einfachere Möglichkeit, dies in Scala zu behandeln, anstatt session.get("foo") == null
? Vielleicht etwas Magie anwenden wie ToOption(session.get("foo"))
und dann kann ich es wie in Scala behandeln
ToOption(session.get("foo")) match {
case Some(_) =>;
case None =>;
}
Das Option
Begleitobjekte apply
-Methode dient als Konvertierungsfunktion von Nullable-Referenzen:
scala> Option(null)
res4: Option[Null] = None
scala> Option(3)
res5: Option[Int] = Some(3)
Das Option
Objekt hat eine apply
Methode, die genau das tut:
var myOptionalString = Option(session.get("foo"));
Beachten Sie, dass die Arbeit mit Java-Objekten nicht wie erwartet funktioniert:
val nullValueInteger : java.lang.Integer = null
val option: Option[Int] = Option(nullValueInteger)
println(option) // Doesn't work - zero value on conversion
val nullStringValue : String = null
val optionString: Option[String] = Option(nullStringValue)
println(optionString) // Works - None value
Dies ist ein sehr altes Thema, aber ein schönes!
Es ist wahr, dass die Umwandlung eines Nicht-Ausnahme-Ergebnisses von Try in Option zu einem Some führt …
scala> Try(null).toOption
res10: Option[Null] = Some(null)
… weil es bei Try nicht um die Überprüfung der Nullfähigkeit geht, sondern nur um eine Möglichkeit, Ausnahmen funktional zu behandeln.
Wenn Sie Try verwenden, um eine Ausnahme abzufangen, und das der Einfachheit halber in eine Option umwandeln, wird None nur angezeigt, wenn eine Ausnahme auftritt.
scala> Try(1/0).toOption
res11: Option[Int] = None
Sie möchten die Werte von Try beibehalten. Das kann null sein.
Aber es stimmt auch, dass die Standardbibliothek manchmal ziemlich verwirrend ist …
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Dieses Verhalten ist etwas inkonsistent, spiegelt jedoch die beabsichtigte Verwendung von Try und Option wider.
Sie verwenden try, um das herauszuholen, was aus einem Ausdruck herauskommt, der Ausnahmen auslösen kann, und Sie kümmern sich nicht um die Ausnahme selbst.
Der Wert, der herauskommen kann, kann sehr wohl eine Null sein. Wenn toOption None gab, Sie konnten nicht zwischen einer Ausnahme und einer Null unterscheidenund das ist nicht schön!
Standalone verwenden Sie Option, um die Existenz oder Nichtexistenz von etwas zu kapseln. In diesem Fall ist Some(null) also None, und das macht Sinn, weil null in diesem Fall die Abwesenheit von etwas darstellt. Hier gibt es keine Zweideutigkeit.
Es ist wichtig anzumerken, dass die referenzielle Transparenz auf keinen Fall gebrochen wird, da .toOption dies ist nicht das gleiche wie Option()
Wenn Sie wirklich durchsetzen müssen BEIDE Ausnahme Sicherheit UND null Sicherheit und Ihren Code muss wirklich nicht zwischen null und einer Ausnahme unterscheiden, Sie müssen nur beide Paradigmen kombinieren! Denn das ist es, was Sie wollen, oder?
Sie können es auf eine Weise tun …
scala> Try(Option(null)).getOrElse(None)
res23: Option[Null] = None
scala> Try(Option(3/0)).getOrElse(None)
res24: Option[Int] = None
scala> Try(Option(3)).getOrElse(None)
res25: Option[Int] = Some(3)
… oder ein anderes …
scala> Try(Option(null)).toOption.flatten
res26: Option[Null] = None
scala> Try(Option(3/0)).toOption.flatten
res27: Option[Int] = None
scala> Try(Option(3)).toOption.flatten
res28: Option[Int] = Some(3)
… oder die lächerlich hässlichsten von ihnen anderen …
scala> Option(Try(null).getOrElse(null))
res29: Option[Null] = None
scala> Option(Try(3/0).getOrElse(null))
res30: Option[Any] = None
scala> Option(Try(3).getOrElse(null))
res31: Option[Any] = Some(3)
Weitere Optionstricks finden Sie unter blog.tmorris.net/scalaoption-cheat-sheet
– Landei
14. Januar 2011 um 16:03 Uhr
Der Link oben sollte sein blog.tmorris.net/posts/scalaoption-cheat-sheet.
– Jacek Laskowski
16. März 2014 um 14:42 Uhr