Je travaille avec play for scala (2.1) et j’ai besoin de convertir une valeur "Option [Long]" en "Long".
Je sais faire le contraire, je veux dire:
def toOption[Long](value: Long): Option[Long] = if (value == null) None else Some(value)
Mais dans mon cas, je dois passer une valeur de "Option [Long]" en tant que type dans une méthode prenant "Long". Toute aide s'il vous plaît.
Tout d’abord, votre mise en oeuvre de «l’inverse» pose de sérieux problèmes. En mettant un paramètre de type nommé Long
sur la méthode, vous masquez le type Long
à partir de la bibliothèque standard. Vous voulez probablement dire ce qui suit à la place:
def toOption(value: Long): Option[Long] =
if (value == null) None else Some(value)
Même cela est un peu absurde (puisque scala.Long
n'est pas un type de référence et ne peut jamais être null
), sauf si vous faites référence à Java.lang.Long
, qui est une recette pour la douleur et la confusion. Enfin, même si vous avez affaire à un type de référence (tel que String
), vous feriez mieux d'écrire le texte suivant, qui est exactement équivalent:
def toOption(value: String): Option[String] = Option(value)
Cette méthode retournera None
si et seulement si value
est null
.
Pour répondre à votre question, supposons que nous ayons la méthode suivante:
def foo(x: Long) = x * 2
En règle générale, vous ne devriez pas penser à passer un Option[Long]
à foo
, mais plutôt à "soulever" foo
dans la Option
via map
:
scala> val x: Option[Long] = Some(100L)
x: Option[Long] = Some(100)
scala> x map foo
res14: Option[Long] = Some(200)
Le but de Option
est de modéliser (au niveau du type) la possibilité d’une valeur "nulle" afin d’éviter toute une classe de problèmes NullPointerException
- y. Utiliser map
sur la Option
vous permet d'effectuer des calculs sur la valeur pouvant figurer dans la Option
tout en continuant à modéliser la possibilité qu'elle soit vide.
Comme une autre réponse le note, il est également possible d’utiliser getOrElse
pour "renflouer" le Option
, mais ce n’est généralement pas l’approche idiomatique de Scala (sauf dans les cas où il existe vraiment une valeur par défaut raisonnable).
Si vous avez x comme option [Long], x.get
vous donnera Long.
Cette méthode est déjà définie sur l'option [A] et s'appelle get :
scala> val x = Some(99L)
x: Some[Long] = Some(99)
scala> x.get
res0: Long = 99
Le problème est que l’appel d’obtenir sur None déclenchera une exception No:
scala> None.get
Java.util.NoSuchElementException: None.get
vous ne gagnerez donc aucun avantage à utiliser un type d'option.
Ainsi, comme indiqué précédemment, vous pouvez utiliser getOrElse si vous pouvez fournir une valeur par défaut raisonnable ou gérer l’exception.
La méthode scala idiomatique consisterait à utiliser une carte ou un outil de compréhension.
x map (_ + 1)
res2: Option[Long] = Some(100)
ou
for (i <- x) yield i +1
res3: Option[Long] = Some(100)
L'option est un moyen de localiser l'effet secondaire (votre fonction peut retourner une valeur vide). Et bon style pour porter votre calcul à Option (l’option est Monad avec les méthodesmap&flatMap).
val x = Option[Long](10)
x.map { a => a + 10 }
Et extraire la valeur avec le traitement manuel des effets secondaires:
val res = x match {
case Some(a) => s"Value: $a"
case None => "no value"
}
Vous devez décider de ce qui se passe lorsque l'option est None
. Fournissez-vous une valeur par défaut?
def unroll(opt: Option[Long]): Long = opt getOrElse -1L // -1 if undefined
unroll(None) // -> -1
Vous pouvez également lancer une exception:
def unroll(opt: Option[Long]): Long = opt.getOrElse(throw
new IllegalArgumentException("The option is expected to be defined at this point")
)
unroll(None) // -> exception
Dans le cas contraire, abstenez-vous d'utiliser null
, à moins que vous n'ayez de très bonnes raisons de l'utiliser (opt.orNull
).
Comme il a déjà été mentionné, getOrElse est probablement ce que vous recherchez pour répondre directement à votre question.
Veuillez également noter que pour convertir une option, vous pouvez simplement:
val myOption = Option(1)
myOption sera maintenant Some (1)
val myOption = Option(null)
myOption sera maintenant None.