En fait le fait d'utiliser Option te force à prendre en compte le cas null/None.
Vu autrement, quand tu as une variable de type A, tu es sûr que c'est bien un A et que tu peux appeler les méthodes de A sans craindre de NPE (Null-Pointer Exception).
Dans la sémantique Java, tu ne peux jamais être sûr qu'une fonction qui renvoie un A ne te renvoie pas null à un moment. Le seul moyen de le savoir est de regarder dans la doc ou de tester à l'exécution.
En Scala/Haskell, une fonction qui renvoie un A renvoie un A. Si jamais il se peut qu'elle ne puisse pas en renvoyer pour une raison quelconque, alors son type de retour est Option[A] et non A et les utilisateurs de la fonction doivent prendre en compte le cas None.
Ça peut servir aussi quand tu veux chaîner des fonctions. Exemple en Java :
a = getA()
if (a == null) abort else {
b = a.getB()
if (b == null) abort else {
c = b.getC()
...
}
L'équivalent si les get renvoyaient des Option serait :
val v = getA().flatMap(_.getB()).flatMap(_.getC())
v match {
case Some(c) => ...
case None => abort
}
ce qui peut s'écrire aussi:
val v = for (a <- getA(), b <- a.getB(), c <- b.getC()) yield c
v match {
case Some(c) => ...
case None => abort
}
[^] # Re: .
Posté par hsyl20 (site web personnel) . En réponse au journal Le point sur Java 7. Évalué à 4.
Vu autrement, quand tu as une variable de type A, tu es sûr que c'est bien un A et que tu peux appeler les méthodes de A sans craindre de NPE (Null-Pointer Exception).
Dans la sémantique Java, tu ne peux jamais être sûr qu'une fonction qui renvoie un A ne te renvoie pas null à un moment. Le seul moyen de le savoir est de regarder dans la doc ou de tester à l'exécution.
En Scala/Haskell, une fonction qui renvoie un A renvoie un A. Si jamais il se peut qu'elle ne puisse pas en renvoyer pour une raison quelconque, alors son type de retour est Option[A] et non A et les utilisateurs de la fonction doivent prendre en compte le cas None.
Ça peut servir aussi quand tu veux chaîner des fonctions. Exemple en Java :
a = getA()
if (a == null) abort else {
b = a.getB()
if (b == null) abort else {
c = b.getC()
...
}
L'équivalent si les get renvoyaient des Option serait :
val v = getA().flatMap(_.getB()).flatMap(_.getC())
v match {
case Some(c) => ...
case None => abort
}
ce qui peut s'écrire aussi:
val v = for (a <- getA(), b <- a.getB(), c <- b.getC()) yield c
v match {
case Some(c) => ...
case None => abort
}