Comment retourner quand un optionnel est vide?
J'aime que options sont dans la norme Java bibliothèque aujourd'hui. Mais il y a un problème de base je continuer à courir dans lequel je n'ai pas trouvé comment le résoudre dans les meilleurs (plus facile à lire et à comprendre, la plus jolie, la plus courte):
Comment retourner à partir d'une méthode lorsqu'une option est vide?
Je suis à la recherche d'une solution générale qui travaille pour différentes combinaisons de nombres d'options et de tailles de blocs de code.
Dans les exemples qui suivent, je vais essayer de montrer ce que je veux dire:
void m1() {
//When I get an optional:
Optional<String> o = getOptional();
//And want to return if it's empty
if (!o.isPresent()) return;
//In the whole rest of the method I have to call Optional.get
//every time I want the value:
System.out.println(o.get());
//Which is pretty ugly and verbose!
}
void m2() {
//If I instead return null if a value is absent:
String s = getNullabe();
if (s == null) return;
//Then I can use the value directly:
System.out.println(s);
}
Cette question est de savoir comment tirer le bon aspect des deux exemples ci-dessus: Le type en toute sécurité de l'option et la brièveté de types nullables.
Le reste des exemples qui illustre ce plus.
void m3() {
//If I on the other hand want to throw on empty that's pretty and compact:
String s = getOptional()
.orElseThrow(IllegalStateException::new);
System.out.println(s);
}
void m4() {
Optional<String> o = getOptional();
if (!o.isPresent()) return;
//I can of course declare a new variable for the un-optionalised string:
String s = o.get();
System.out.println(s);
//But the old variable still remains in scope for the whole method
//which is ugly and annoying.
System.out.println(o.get());
}
void m5() {
//This is compact and maybe pretty in some ways:
getOptional().ifPresent(s -> {
System.out.println(s);
//But the extra level of nesting is annoying and it feels
//wrong to write all the code in a big lambda.
getOtherOptional().ifPresent(i -> {
//Also, more optional values makes it really weird and
//pretty hard to read, while with nullables I would
//get no extra nesting, it would looks good and be
//easy to read.
System.out.println("i: " + i);
//It doesn't work in all cases either way.
});
});
}
Optional<String> getOptional() {
throw new UnsupportedOperationException();
}
Optional<Integer> getOtherOptional() {
throw new UnsupportedOperationException();
}
String getNullabe() {
throw new UnsupportedOperationException();
}
Comment puis-je retourner à partir d'une méthode si une option est vide, sans avoir à utiliser get
dans le reste de la méthode, sans déclarer une variable supplémentaire et sans niveaux supplémentaires de bloc de nidification?
Ou s'il n'est pas possible d'obtenir tout cela, quelle est la meilleure façon de gérer cette situation?
source d'informationauteur Lii
Vous devez vous connecter pour publier un commentaire.
Vous pouvez utiliser
orElse(null)
:Vous pouvez utiliser
ifPresent
etmap
méthodes au lieu de cela, si la fonction est nulle, et vous avez besoin de faire des effets secondaires que vous pouvez utiliserifPresent
,Si un autre retour de méthode s'appuie sur l'Option que cette méthode peut avoir besoin de revenir une Option et ainsi utiliser la méthode map
Plus du temps lorsque vous appelez
isPresent
etget
vous font un mauvais usage deOptional
.La ifPresent que vous utilisez ne vous demande pas de créer un nouveau lambda, vous pouvez simplement utiliser une méthode de référence:
Cela ne résout pas véritablement le cas où vous souhaitez conditionner sur la présence de deux options, si. Mais, comme une alternative à
pourquoi ne pas simplement l'inverse de l'état, qui fonctionne très bien dans le imbriqués cas, trop? Il n'y a pas besoin d'effectuer un retour explicite:
Toutefois, ce genre de cas d'utilisation, suggère que vous n'êtes pas vraiment bénéficiant de l'Option, par opposition à un nullable valeur. En général, si vous utilisez isPresent et d'obtenir, en Option peut ne pas être vraiment pour vous que beaucoup (sauf qu'il vous oblige à considérer le cas où la valeur est manquante). À l'aide de ifPresent, map, filter, et d'autres "plus fonctionnelle" méthodes pourraient être plus typique utilise pour une valeur Facultative.
Mais en tout cas, merci de ne pas retourner la valeur null lorsque vous promet une Option. Mais il est parfaitement légal de retourner la valeur null lorsqu'un objet est attendre, le point de l'Option est précisément pour éviter d'avoir à vérifier la valeur null. Donc, ne pas faire:
mais au lieu de faire:
Sinon vous finissez par avoir à faire:
qui est vraiment juste de faire le même genre de chose deux fois. L'utilisation d'une Option, ou d'utiliser un nullable valeur, mais ne pas faire les deux!
Je ne pense pas que ce que vous me demandez, c'est effectivement possible, mais je voudrais suggère simplement de prendre toutes vos code qui fonctionne directement sur votre Chaîne et l'envelopper dans une fonction. Si votre fonction devient quelque chose comme ceci:
Cette façon, vous n'avez de la Chaîne dans le champ d'application et que vous n'avez pas à appeler
.get()
chaque fois que vous souhaitez accéder.