wake-up-neo.com

Option "Konvertieren" [x] in Scala in x

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. 

18
mahoosh

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 valuenull 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).

26
Travis Brown

Wenn Sie x als Option [Long] haben, gibt Ihnen x.get Long.

39
Dao Lam

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)
7
Andreas Neumann

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"
} 
2
Yuriy

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).

1
0__

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.

0