Es gibt zwei wichtige Unterschiede. Zunächst wird Option
ein None
zurück, wenn ihr Argument ist null:
scala> val x: Option[String] = Some(null)
x: Option[String] = Some(null)
scala> val y: Option[String] = Option(null)
y: Option[String] = None
Dies kann nützlich sein, aber es ist nicht immer das, was Sie wollen, und (was genauso wichtig ist) schlägt vor, dass es eine vernünftige Chance, dass das Argument kann in einigen Fällen null sein, was irreführend sein kann.
Some
ist besser geeignet für Fälle, in denen Sie einen Option
um einen Wert, den Sie wissen, nicht null ist. Leider ist der zweite Unterschied, dass der Rückgabetyp von Some(foo)
ist Some[Whatever]
, nicht Option[Whatever]
, die wirklich in einigen Situationen unbequem sein kann, in denen Some
abgeleitet bedeutet, dass Sie Typfehler erhalten, wenn Sie versuchen, None
oder Option
in bestimmten Positionen später zu verwenden. In diesen Fällen müssen Sie Some(foo): Option[Whatever]
verwenden, was ziemlich unangenehm ist.
Angenommen, wir haben eine Liste von Strings, die (wir hoffen) ganze Zahlen darstellen, und wir wollen sie analysieren und summieren. Wir wollen eine None
, wenn es einen Parsing-Fehler gibt und eine Some(total)
andernfalls. Im Folgenden ist eine ziemlich vernünftige Möglichkeit, dies in einem einzigen Durchquerung mit der Standardbibliothek zu tun:
List("1", "2", "3").foldLeft(Some(0)) {
case (acc, item) => for {
t <- acc
n <- util.Try(item.toInt).toOption
} yield t + n
}
Abgesehen davon, dass dies nicht funktioniert-wir bekommen einen Typfehler:
<console>:10: error: type mismatch;
found : Option[Int]
required: Some[Int]
t <- acc
^
Wir beheben dies durch Schreiben .foldLeft(Some(0): Option[Int])
, aber hugh.
Dies ist kein Problem in Ihrem speziellen Beispiel, da der Rückgabetyp explizit Option[Int]
ist, so dass Sie sich keine Gedanken über Typinferenz machen müssen. In diesem Fall ist Some(a)
die richtige Wahl.
Als Randbemerkung, Scalaz bietet some
und none
Konstrukteuren, die Sie Typinferenz Problem und laut Lösungen wie Some(foo): Option[Whatever]
vermeiden helfen:
scala> import scalaz._, Scalaz._
import scalaz._
import Scalaz._
scala> some(10)
res0: Option[Int] = Some(10)
scala> none[Int]
res1: Option[Int] = None
Beiden Rückgabetypen sind Option
, die Folgerung viel einfacher macht Art. Sie können diese sich trivialer definieren, wenn Sie Scalaz nicht verwenden möchten:
scala> def some[A](a: A): Option[A] = Some(a)
some: [A](a: A)Option[A]
scala> def none[A]: Option[A] = None
none: [A]=> Option[A]
Wenn Sie diese anstelle von Some
verwenden und None
Sie haben nie über eine unangemessen bestimmte Art wird gefolgert zu kümmern.
Zusammenfassend: Verwenden Sie Option(foo)
nur in Situationen, in denen das Argument Null sein kann (was idealerweise nur für Dinge wie Interoperabilität mit Java sein sollte).Verwenden Sie Some(foo)
in Fällen, in denen der Wert explizit als Option
eingegeben wurde. Wenn der abgeleitete Typ Some[Whatever]
lautet, fügen Sie eine Annotation : Option[Whatever]
hinzu oder verwenden Sie etwas wie Scalaz some
.
Es gibt Unterschiede in ihrem Verhalten - versuchen Sie einfach 'Some [String] (null)' und 'Option [String] (null)'. –
Sie haben völlig Recht mit ihrer Initialisierung und Sie haben diesen Benutzerfall in Ihrer Antwort ganz klar erklärt! Ich werde meine Antwort bearbeiten, um genau zu sein. – ipoteka