web-dev-qa-db-fra.com

Option "Convertir" [x] en x dans Scala

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. 

18
mahoosh

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

26
Travis Brown

Si vous avez x comme option [Long], x.get vous donnera Long.

39
Dao Lam

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

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

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

1
0__

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.

0
Christopher Hunt