Pourquoi est-foreach mieux que d'obtenir pour les options Scala?
-
26-10-2019 - |
Question
Pourquoi utiliser foreach
, map
, flatMap
etc. sont considérés comme mieux que d'utiliser get
pour les options Scala? Si j'useisEmpty
je peux appeler get
en toute sécurité.
La solution
Eh bien, ce genre de revient à « dire, ne demande pas ». Tenez compte de ces deux lignes:
if (opt.isDefined) println(opt.get)
// versus
opt foreach println
Dans le premier cas, vous êtes à la recherche à l'intérieur opt
puis réagir en fonction de ce que vous voyez. Dans le second cas, vous dites simplement opt
ce que vous voulez faire, et de le laisser faire face.
Le premier cas en sait trop sur Option
, reproduit la logique interne, est fragile et sujette à des erreurs (il peut entraîner des erreurs d'exécution, au lieu des erreurs de compilation, si elle était écrite correctement).
Ajoutez à cela, il est composable. Si vous disposez de trois options, une seule pour la compréhension prend soin d'eux:
for {
op1 <- opt1
op2 <- opt2
op3 <- opt3
} println(op1+op2+op3)
Avec if
, les choses commencent à obtenir rapidement désordre.
Autres conseils
Une belle raison d'utiliser foreach
est l'analyse quelque chose avec des options imbriquées. Si vous avez quelque chose comme
val nestedOption = Some(Some(Some(1)))
for {
opt1 <- nestedOption
opt2 <- opt1
opt3 <- opt2
} println(opt3)
La console affiche 1
. Si vous étendez à un cas où vous avez une classe qui stocke en option une référence à quelque chose, ce qui dans les magasins à son tour une autre référence, pour compréhensions vous permettent d'éviter une « pyramide » géant de None / Certains contrôles.
Il y a déjà d'excellentes réponses à la question réelle, mais pour plus Option
-foo vous devriez certainement vérifier Tony Morris Option Cheat Sheet .
La raison pour laquelle il est plus utile d'appliquer des choses comme map
, foreach
et flatMap
directement au Option
au lieu d'utiliser get
puis exécuter la fonction est qu'il fonctionne soit sur Some
ou None
et vous ne « t doivent faire des vérifications spéciales pour vous assurer que la valeur est là.
val x: Option[Int] = foo()
val y = x.map(_+1) // works fine for None
val z = x.get + 1 // doesn't work if x is None
Le résultat de y
est ici un Option[Int]
, ce qui est souhaitable car si x
est facultative, alors y
peut être indéterminée aussi bien. Depuis get
ne fonctionne pas sur None
, vous auriez à faire un tas de travail supplémentaire pour vous assurer que vous n'avez pas d'erreurs; travail supplémentaire qui est fait pour vous par map
.
Plus simplement:
-
Si vous avez besoin de faire quelque chose (une procédure lorsque vous n'avez pas besoin de saisir la valeur de retour de chaque appel) que si l'option est définie (par exemple est un
Some
): utilisationforeach
(si vous vous souciez les résultats de chaque appel, l'utilisationmap
) -
Si vous avez besoin de faire quelque chose si l'option définie et quelque chose d'autre si ce n'est pas: l'utilisation
isDefined
dans une instruction if -
Si vous avez besoin de la valeur si l'option est un
Some
, ou une valeur par défaut si elle est unNone
: utilisationgetOrElse
Essayer d'effectuer nos opérations avec get
est plus style impératif où u besoin de tel ce qu'il faut faire et comment le faire . En d'autres termes, nous dictez les choses et creuser plus dans les entrailles de Options
. Où que map,flatmap
sont de façon plus fonctionnelle de faire les choses où nous sommes par exemple ce qu'il faut faire, mais pas comment faire .