Prenez les deux exemples de code:
if(optional.isPresent()) {
//do your thing
}
if(variable != null) {
//do your thing
}
Autant que je sache, la différence la plus évidente est que l'option Facultatif nécessite la création d'un objet supplémentaire.
Cependant, de nombreuses personnes ont commencé à adopter rapidement les options. Quel est l'avantage d'utiliser des options par rapport à une vérification nulle?
if
déclarations sont tellement la dernière décennie, et tout le monde utilise des abstractions de monade et des lambdas maintenant.if(x.isPresent) fails_on_null(x.get)
vous quittez le système de type et devez garder la garantie que le code ne se cassera pas "dans votre tête" sur la distance (certes courte) entre la condition et l'appel de fonction. Dansoptional.ifPresent(fails_on_null)
le système de type, cette garantie est faite pour vous, et vous n'avez pas à vous inquiéter.Optional.ifPresent
(et diverses autres constructions Java) est que vous ne pouvez modifier efficacement que les variables finales et ne pouvez pas lever d'exceptions vérifiées. C'est une raison suffisante pour éviter souventifPresent
, malheureusement.Réponses:
Optional
exploite le système de typage pour effectuer un travail que vous auriez autrement dû faire tout dans votre tête: se rappeler si une référence donnée peut être ou nonnull
. C'est bon. Il est toujours intelligent de laisser le compilateur gérer des travaux ennuyeux et de réserver la pensée humaine à un travail créatif et intéressant.Sans
Optional
, chaque référence dans votre code est comme une bombe non explosée. L'accès peut faire quelque chose d'utile, ou bien il peut mettre fin à votre programme avec une exception.Avec Facultatif et sans
null
, chaque accès à une référence normale réussit, et chaque référence à une Option réussit à moins qu'il ne soit pas défini et que vous n'ayez pas vérifié cela. C'est une énorme victoire en maintenabilité.Malheureusement, la plupart des langues actuellement proposées
Optional
n'ont pas été aboliesnull
, vous ne pouvez donc que profiter du concept en instituant une politique stricte de «absolument nonnull
, jamais». Par conséquent,Optional
par exemple, Java n'est pas aussi convaincant qu'il devrait idéalement l'être.la source
Optional
juste pour vous rappeler que la valeur pourrait être nulleUn
Optional
apporte un typage plus fort dans les opérations qui peuvent échouer, comme les autres réponses l'ont couvert, mais c'est loin d'être la chose la plus intéressante ou la plus précieuse àOptionals
apporter. Beaucoup plus utile est la possibilité de retarder ou d'éviter la vérification d'échec, et de composer facilement de nombreuses opérations qui peuvent échouer.Considérez si vous aviez votre
optional
variable de votre exemple de code, alors vous avez dû effectuer deux étapes supplémentaires qui pourraient potentiellement échouer chacune. Si une étape échoue, vous souhaitez renvoyer une valeur par défaut à la place. En utilisantOptionals
correctement, vous vous retrouvez avec quelque chose comme ceci:Avec,
null
j'aurais dû vérifier trois foisnull
avant de continuer, ce qui ajoute beaucoup de complexité et de maux de tête de maintenance au code.Optionals
avoir cette vérification intégrée aux fonctionsflatMap
etorElse
.Notez que je n'ai pas appelé
isPresent
une seule fois, ce que vous devriez considérer comme une odeur de code lors de l'utilisationOptionals
. Cela ne signifie pas nécessairement que vous ne devriez jamais utiliserisPresent
, juste que vous devriez examiner attentivement tout code qui le fait, pour voir s'il existe une meilleure façon. Sinon, vous avez raison, vous n'obtenez qu'un avantage de sécurité de type marginal sur l'utilisationnull
.Notez également que je ne suis pas aussi inquiet à l'idée d'encapsuler tout cela dans une seule fonction, afin de protéger les autres parties de mon code contre les pointeurs nuls des résultats intermédiaires. S'il est plus logique d'avoir mon
.orElse(defaultValue)
dans une autre fonction par exemple, j'ai beaucoup moins de scrupules à le mettre là-bas, et il est beaucoup plus facile de composer les opérations entre différentes fonctions selon les besoins.la source
Il met en évidence la possibilité de null comme réponse valide, ce que les gens supposent souvent (à tort ou à raison) ne sera pas retourné. Mettre en évidence les quelques fois où null est valide permet d'omettre de jeter votre code avec un grand nombre de vérifications nulles inutiles.
Idéalement, la définition d'une variable sur null serait une erreur de compilation n'importe où, mais en option; éliminer les exceptions de pointeur nul à l'exécution. De toute évidence, la rétrocompatibilité empêche cela, malheureusement
la source
Laisse moi te donner un exemple:
Il est assez clair à quoi cette méthode est destinée. Mais que se passe-t-il si le référentiel ne contient pas d'utilisateur avec un identifiant donné? Il pourrait lever une exception ou peut-être qu'il renvoie null?
Deuxième exemple:
Maintenant, que se passe-t-il ici s'il n'y a pas d'utilisateur avec un identifiant donné? À droite, vous obtenez une instance Optional.absent () et vous pouvez la vérifier avec Optional.isPresent (). La signature de méthode avec Facultatif est plus explicite sur son contrat. Il est immédiatement clair, comment la méthode est censée se comporter.
Il présente également un avantage lors de la lecture du code client:
J'ai formé mon œil pour voir .get () comme une odeur de code immédiate. Cela signifie que le client ignore délibérément le contrat de la méthode invoquée. Il est beaucoup plus facile de voir cela que sans optionnel, car dans ce cas, vous ne savez pas immédiatement quel est le contrat de la méthode appelée (si elle autorise null ou non dans son retour), vous devez donc le vérifier d'abord.
Facultatif est utilisé avec la convention selon laquelle les méthodes avec le type de retour Facultatif ne retournent jamais null et généralement aussi avec la convention (moins forte) cette méthode sans le type de retour facultatif ne renvoie jamais null (mais il est préférable de l'annoter avec @Nonnull, @NotNull ou similaire) .
la source
Un
Optional<T>
vous permet d'avoir "échec" ou "aucun résultat" comme valeur de réponse / retour valide pour vos méthodes (pensez, par exemple, à une recherche de base de données). L'utilisation d'unOptional
au lieu d'utilisernull
pour indiquer un échec / aucun résultat présente certains avantages:null
peut être retourné.null
devrait, au moins à mon avis, pas être utilisé pour indiquer quoi que ce soit la sémantique pourrait ne pas être tout à fait clair. Il doit être utilisé pour indiquer au ramasse-miettes que l'objet mentionné précédemment peut être collecté.Optional
classe fournit de nombreuses méthodes intéressantes pour travailler conditionnellement avec les valeurs (par exemple,ifPresent()
) ou définir les valeurs par défaut de manière transparente (orElse()
).Malheureusement, cela ne supprime pas complètement la nécessité de
null
vérifier le code, car l'Optional
objet lui-même pourrait toujours l'êtrenull
.la source
En plus des autres réponses, l'autre avantage majeur des options quand il s'agit d'écrire du code propre est que vous pouvez utiliser une expression Lambda dans le cas où la valeur est présente, comme indiqué ci-dessous:
la source
Considérez la méthode suivante:
Voyons maintenant un code d'appel:
Cela provoque un accident potentiellement difficile à suivre ailleurs, car
dance
ne s'attendait pas à une valeur nulle.Cela provoque une erreur de compilation, car la danse attendait un
Person
pas unOptional<Person>
Si je n'avais pas de personne, cela provoque une exception sur cette ligne, au point où j'ai tenté de convertir le
Optional<Person>
en personne. La clé est que, contrairement au passage d'une valeur nulle, les traces exceptées ici, pas un autre emplacement dans le programme.Pour mettre tout cela ensemble: une mauvaise utilisation en option produit plus facilement des problèmes de recherche, une mauvaise utilisation de null entraîne des problèmes difficiles à localiser.
la source
Optional.get()
votre code est mal écrit - vous ne devriez presque jamais appeler Optional.get sans vérifier d'Optional.isPresent()
abord (comme indiqué dans l'OP) ou vous pourriez écrireoptionalPersion.ifPresent(myObj::dance)
.Dans Objective-C, toutes les références d'objet sont facultatives. Pour cette raison, un code comme celui que vous avez publié est stupide.
Un code comme celui-ci est inconnu dans Objective-C. Au lieu de cela, le programmeur devrait simplement:
Si
variable
contient une valeur, alorsdoThing
sera appelé dessus. Sinon, pas de mal. Le programme le traitera comme un no-op et continuera à fonctionner.C'est le véritable avantage des options. Vous n'avez pas besoin de salir votre code
if (obj != nil)
.la source
Le problème évident ici est que si "facultatif" vraiment est manquant (c'est-à-dire est nul) alors votre code va exploser avec une NullReferenceException (ou similaire) essayant d'appeler n'importe quelle méthode sur une référence d'objet null!
Vous voudrez peut-être écrire une méthode statique de classe Helper qui détermine la nullité de tout type d'objet donné, quelque chose comme ceci:
ou, peut-être, plus utilement:
Mais l'un ou l'autre de ces éléments est-il vraiment plus lisible / compréhensible / maintenable que l'original?
la source