Comprendre les options dans Scala
-
le type
Option
en Scala -
Récupérer la valeur de l’
Option
en Scala -
l’
Option
comme conteneur dans Scala
![Comprendre les options dans Scala](/img/Scala/ag-feature-image---understanding-options-in-scala.webp)
Dans cet article, nous allons apprendre à travailler avec des éléments de données facultatifs dans Scala. Les Options
de Scala nous aident à écrire du code robuste.
le type Option
en Scala
Option[T]
dans une Scala est un conteneur
stockant zéro ou une valeur d’un type donné. En gérant les valeurs facultatives à l’aide de Option
de Scala, nous pouvons garantir deux choses :
- Sécurité de type : Nous pouvons paramétrer les valeurs facultatives.
- Conscience fonctionnelle : Le type
option
fournit de nombreuses capacités fonctionnelles qui garantissent que moins de bogues sont créés dans le programme.
Dans Scala, une Option[T]
est représentée soit par un objet Some[T]
ou None[T]
. Ici scala.Option
est la classe de base qui est abstraite et étendue, ce qui fait que Option
dans Scala se comporte comme un conteneur.
Rappelons que la classe Option
et ses sous-classes nécessitent un type concret. Ils peuvent être explicites ou déduits comme la syntaxe suivante.
Exemple:
val obj1: Option[Int] = None
val obj2 = Some(100)
Ici obj1
et obj2
sont des objets de Option[Int]
. Une question courante est de savoir comment vérifier si notre Option
est Some
ou None
?
Pour résoudre ce problème, nous avons les fonctions suivantes.
isEmpty
: cette méthode renvoietrue
si l’objet estNone
.nonEmpty
: cette méthode renvoietrue
si l’objet estSome
.isDefined
: cette méthode renvoietrue
si l’objet estSome
.
Récupérer la valeur de l’Option
en Scala
Nous pouvons utiliser la méthode get
pour récupérer la valeur Options
. Si la méthode get
est invoquée sur un objet de None
, alors NoSuchElementException
est levée, également appelée biais de succès
.
Exemple de code :
val obj1: Option[Int]= ...
val v1 = if (obj1.isDefined)
{
obj1.get
}
else
{
0
}
Le code ci-dessus peut également être écrit en utilisant la correspondance de modèle.
Exemple de code :
val obj1: Option[Int]= ...
val v1 = obj1 match {
case Some(temp) =>
temp
case None =>
0
}
Nous avons aussi d’autres méthodes comme getOrElse
et orElse
pour récupérer des valeurs.
getOrElse
: Cette méthode récupère des valeurs si l’objet estSome
; sinon, il renvoie une valeur par défaut.orElse
: Cette méthode récupère des valeurs si l’objet estSome
; sinon renvoie unealternate
Option.
Lorsque la valeur optionnelle n’est pas définie, la méthode getOrElse
est très utile car nous pouvons renvoyer une valeur par défaut.
Syntaxe:
val v1 = obj1.getOrElse(0)
l’Option
comme conteneur dans Scala
Comme nous avons vu que Option
est un conteneur dans Scala pour une autre valeur, tout comme nous parcourons une List
de la même manière, nous pouvons parcourir une Option
.
Regardons quelques méthodes pour ce conteneur. Syntaxe de la méthode Option.map
en Scala :
final def map[Y](f: (X) => Y): Option[Y]
Exemple de code :
val obj1: Option[Int] = Some(100)
assert(obj1.map(_.toString).contains("100"))
assert(obj1.map(_ * 2.0).contains(200))
val obj2: Option[Int] = None
assert(obj2.map(_.toString).isEmpty)
Dans l’exemple ci-dessus, nous avons utilisé la méthode Option.map
pour convertir les valeurs contenues dans un autre type. La méthode Option.map
pourrait également être utilisée pour affecter le contrôle de flux
du programme.
Exemple de code :
val obj1: Option[Int] = Some(10)
val obj2: Option[Int] = None
def mul(n: Int): Int = n * 2
assert(obj1.map(mul).contains(20))
assert(obj2.map(mul).isEmpty)
Ici, nous avons créé deux objets de Option[Int]
, le premier objet a une valeur de 10
, et le second est vide. Puis nous avons défini une méthode mul
qui multiplie l’entrée par 2
.
Enfin, nous mappons obj1
et obj2
en utilisant la méthode mul
. Le mapping obj1 nous donne Some(20)
, et le mapping obj2 nous donne None
.
Une chose à observer ici est que dans le second appel, obj2.map(mul)
, la méthode mul
n’est pas appelée du tout. Nous pouvons également contrôler le flux avec filtrage.
Nous avons plusieurs méthodes pour le faire :
filter
: Cette méthode renvoieOption
si la valeurOptions
estSome
et la fonction fournie renvoietrue
.exists
: cette méthode renvoietrue
si l’Option
est définie et que la fonction fournie renvoietrue
.forall
: se comporte de la même manière que la méthodeexists
.
En utilisant ces fonctions, nous pouvons écrire le code de manière très concise.
Prenons un exemple où nous trouvons l’équipe qui a obtenu le meilleur score.
Exemple de code :
def highScoringTeam(playerA: Player, playerB: Player, tournament: Tournament): Option[(Player, Int)] =
{ getTopScore(playerA, tournament).foldRight(getTopScore(playerB, tournament)) {
case (playerAInfo, playerBInfo) => playerBInfo.filter {
case (_, scoreB) => scoreB > playerAInfo._2
}.orElse(Some(playerAInfo))
}
}
Dans le code ci-dessus, nous avons tiré parti du fait que Options
peut être utilisé comme collections. La seule différence est qu’une option peut avoir au plus une valeur.