Wrapping null-Verfahren zum Zurückkehren in Java mit der Option in Scala?
-
11-10-2019 - |
Frage
Nehmen wir an ich eine Methode session.get(str: String): String
haben, aber Sie wissen nicht, ob es ein String oder ein Null zurück, weil sie von Java kommt.
Gibt es einen einfacheren Weg, dies statt session.get("foo") == null
in Scala zu behandeln? Vielleicht gelten einige Zauber wie ToOption(session.get("foo"))
und dann kann ich es in Scala Art und Weise behandeln, wie
ToOption(session.get("foo")) match {
case Some(_) =>;
case None =>;
}
Lösung
Der Option
Begleiter Objekts apply
Methode dient als Umwandlungsfunktion von Nullable-Referenzen:
scala> Option(null)
res4: Option[Null] = None
scala> Option(3)
res5: Option[Int] = Some(3)
Andere Tipps
Das Option
Objekt hat eine apply
method, die genau das tut:
var myOptionalString = Option(session.get("foo"));
, dass Hinweis bei der Arbeit mit Java-Objekte wird es nicht wie erwartet funktionieren:
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 nice one!
Es ist wahr, dass jede Nicht Ausnahme Ergebnis von Versuchen Sie Option Umwandlung in einem Einige führen wird ...
scala> Try(null).toOption
res10: Option[Null] = Some(null)
... weil Versuchen nicht über NULL-Zulässigkeit Prüfung ist aber nur eine Möglichkeit, funktionell Ausnahmen zu behandeln.
Versuchen Sie es mit einer Ausnahme zu fangen und zu konvertieren, das zu einer Option für die Bequemlichkeit nur Keine bei zeigen eine Ausnahme geschieht.
scala> Try(1/0).toOption
res11: Option[Int] = None
Sie mögen die Werte erhalten, die von Versuchen herauskommen. Das kann null sein.
Aber es ist auch wahr, dass der Standard-lib ganz manchmal verwirrend ...
scala> Try(null).toOption
res12: Option[Null] = Some(null)
scala> Option(null)
res13: Option[Null] = None
Dieses Verhalten ist ein bisschen widersprüchlich, aber es spiegelt die Art intented Nutzung sowohl Try and Option.
Sie nutzen versuchen, was zu bekommen kommt eines Ausdrucks aus, die Ausnahmen auslösen kann, und Sie kümmern sich nicht um die Ausnahme selbst.
Der Wert, kann sehr gut herauskommen kann eine Null sein. Wenn toOption Keinen gab, konnte man nicht differenciate zwischen einer Ausnahme und einer Null , und das ist nicht schön!
Standalone, verwenden Sie Option, um das Vorhandensein oder Nichtvorhandensein von etwas zu verkapseln. Also in diesem Fall Einige (null) ist keine, und das macht Sinn, weil null in diesem Fall das Fehlen von etwas darstellt. Es gibt keine Mehrdeutigkeit hier.
Es ist wichtig, dass in jedem Fall referencial Transparenz zu bemerken ist nicht gebrochen, da .toOption ist nicht die gleiche wie Option ()
Wenn Sie wirklich erzwingen müssen BEIDE Ausnahme Sicherheit und null Sicherheit und Code wirklich braucht wirklich nicht zu differenzieren zwischen null und einer Ausnahme , müssen Sie nur die beiden Paradigmen kombinieren! Weil gut, das ist, was Sie wollen, nicht wahr?
Sie können es in einer Art und 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 eine andere ...
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 lächerlich hässlichste von ihnen Anothers ...
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)