Dies ist ein sehr altes Thema, aber ein schönes!
Es ist wahr, dass das Konvertieren eines Nicht-Ausnahme-Ergebnisses von Try to Option zu einem ...
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 versuchen, eine Ausnahme abzufangen, und diese zur Vereinfachung in eine Option konvertieren, wird Keine angezeigt, falls 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 ist auch wahr, 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 alles aus einem Ausdruck herauszuholen, der Ausnahmen auslösen kann, und die Ausnahme selbst ist Ihnen egal.
Der Wert, der herauskommen kann, kann sehr gut eine Null sein. Wenn toOption None gab, konnte man nicht zwischen einer Ausnahme und einer Null unterscheiden , und das ist nicht schön!
Standalone verwenden Sie Option, um die Existenz oder Nicht-Existenz von etwas zu kapseln. In diesem Fall ist Some (null) None, und das ist sinnvoll, da null in diesem Fall das Fehlen von etwas darstellt. Hier gibt es keine Mehrdeutigkeit.
Es ist wichtig zu beachten, dass die referenzielle Transparenz auf keinen Fall beeinträchtigt wird, da .toOption nicht mit Option () identisch ist.
Wenn Sie wirklich BEIDE Ausnahmesicherheit UND Nullsicherheit erzwingen müssen und Ihr Code wirklich nicht wirklich zwischen Null und einer Ausnahme unterscheiden muss , müssen Sie nur beide Paradigmen kombinieren! Denn genau das willst du, 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 der lächerlich hässlichste von ihnen ...
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)