Ich arbeite mit play for scala (2.1) und muss einen Wert für "Option [Long]" in "Long" konvertieren.
Ich weiß, wie man das Gegenteil macht, ich meine:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
In meinem Fall muss ich jedoch den Wert "Option [Long]" als Typ an eine Methode übergeben, die "Long" benötigt. .__ Jede hilfe bitte.
Zuallererst hat Ihre Implementierung des "Gegenteils" einige ernsthafte Probleme. Durch Setzen eines Typparameters mit dem Namen Long
für die Methode spiegeln Sie den Typ Long
aus der Standardbibliothek. Sie meinen wahrscheinlich stattdessen Folgendes:
def toOption(value: Long): Option[Long] =
if (value == null) None else Some(value)
Auch das ist irgendwie unsinnig (da scala.Long
kein Referenztyp ist und niemals null
sein kann), es sei denn, Sie beziehen sich auf Java.lang.Long
, ein Rezept für Schmerz und Verwirrung. Selbst wenn Sie sich mit einem Referenztyp befassen (wie String
), sollten Sie das Folgende besser schreiben, was genau gleichwertig ist:
def toOption(value: String): Option[String] = Option(value)
Diese Methode gibt None
nur dann zurück, wenn value
null
ist.
Angenommen, wir haben die folgende Methode, um Ihre Frage zu beantworten:
def foo(x: Long) = x * 2
Im Allgemeinen sollten Sie nicht daran denken, einen Option[Long]
an foo
zu übergeben, sondern eher daran, foo
über Option
in die map
zu "heben":
scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)
scala> x map foo
res14: Option[Long] = Some(200)
Der ganze Sinn von Option
besteht darin, (auf der Typebene) die Möglichkeit eines "Nullwerts" zu modellieren, um eine ganze Klasse von NullPointerException
- y-Problemen zu vermeiden. Wenn Sie map
für die Option
verwenden, können Sie Berechnungen für den Wert durchführen, der sich in der Option
befindet, während Sie weiterhin die Möglichkeit modellieren, dass er leer ist.
Als weitere Antwortnotizen ist es auch möglich, getOrElse
zu verwenden, um die Option
zu "retten". Dies ist in der Regel jedoch nicht der idiomatische Ansatz in Scala (außer in Fällen, in denen ein angemessener Standardwert vorhanden ist).
Wenn Sie x als Option [Long] haben, gibt Ihnen x.get
Long.
Diese Methode ist bereits in Option [A] definiert und heißt get :
scala> val x = Some(99L)
x: Some[Long] = Some(99)
scala> x.get
res0: Long = 99
Das Problem ist, dass der Aufruf von get on None eine NoSucheElement-Ausnahme auslöst:
scala> None.get
Java.util.NoSuchElementException: None.get
sie profitieren also nicht von der Verwendung eines Option-Typs.
Wie bereits erwähnt, können Sie getOrElse verwenden, wenn Sie einen sinnvollen Standardwert angeben oder die Exception behandeln können.
Die idiomatische Scala-Methode wäre die Verwendung einer Karte oder eines Verständnisses
x map (_ + 1)
res2: Option[Long] = Some(100)
oder
for (i <- x) yield i +1
res3: Option[Long] = Some(100)
Option ist eine Möglichkeit, Nebeneffekte zu lokalisieren (Ihre Funktion kann einen leeren Wert zurückgeben). Und eine gute Methode, um Ihre Berechnung auf Option zu heben (Option ist Monad mitmap&flatMapmethod).
val x = Option[Long](10)
x.map { a => a + 10 }
Und extrahieren Sie den Wert mit der manuellen Verarbeitung des Nebeneffekts:
val res = x match {
case Some(a) => s"Value: $a"
case None => "no value"
}
Sie müssen entscheiden, was passiert, wenn die Option None
ist. Geben Sie einen Standardwert an?
def unroll(opt: Option[Long]): Long = opt getOrElse -1L // -1 if undefined
unroll(None) // -> -1
Sie könnten auch eine Ausnahme auslösen:
def unroll(opt: Option[Long]): Long = opt.getOrElse(throw
new IllegalArgumentException("The option is expected to be defined at this point")
)
unroll(None) // -> exception
Verwenden Sie in diesem Fall null
nicht, es sei denn, Sie haben sehr gute Gründe (opt.orNull
).
Wie bereits erwähnt, ist getOrElse wahrscheinlich das, was Sie suchen, wenn Sie Ihre Frage direkt beantworten.
Bitte beachten Sie auch, dass Sie zum Konvertieren in eine Option einfach:
val myOption = Option(1)
myOption wird jetzt einige sein (1)
val myOption = Option(null)
myOption wird jetzt None sein.