web-dev-qa-db-fra.com

Retour booléen de set.add () in if conditionnel?

L'opérateur add de la classe set renvoie un booléen qui est vrai si l'élément (qui doit être ajouté) n'était pas déjà là, et faux sinon. Est en train d'écrire

if (set.add(entry)) {
    //do some more stuff
}

considéré comme un bon style en termes d'écriture de code propre? Je me demande puisque vous faites deux choses à la fois. 1) ajouter l'élément et 2) vérifier si l'élément existait.

15
Andreas Braun

Oui, ça l'est.

Le point habituel pour qu'une opération retourne une valeur booléenne est que vous pouvez l'utiliser pour prendre des décisions, c'est-à-dire dans une construction if. La seule autre façon de réaliser ce potentiel serait de stocker la valeur de retour dans une variable, puis de la réutiliser immédiatement dans une if, ce qui est tout simplement idiot et certainement pas préférable à l'écriture de la fonction if(operation()) { ... }. Alors allez-y et faites-le, nous ne vous jugerons pas (pour cela).

19
Kilian Foth

Je dirais que ce n'est pas aussi propre que possible, car cela oblige le responsable à savoir ou à rechercher ce que signifie la valeur de retour. Cela signifie-t-il que la valeur existait déjà, n'existait pas déjà, a été insérée avec succès? Si vous ne l'utilisez pas beaucoup, vous ne le saurez pas, et même si vous le faites, c'est beaucoup plus de charge mentale.

Je préférerais ce qui suit:

boolean added = set.add(entry);

if (added) {
    //do some more stuff
}

Oui, un peu plus verbeux, mais le compilateur devrait générer à peu près exactement le même bytecode, et même les personnes qui n'ont pas utilisé Java ensembles depuis des années peuvent suivre la logique sans rien rechercher).

12
Karl Bielefeldt

Si vrai signifie succès, alors c'est du bon code clair.

Il existe une convention répandue selon laquelle une fonction ou une méthode renvoie true (ou quelque chose qui s'évalue à true) en cas de succès. Tant que votre code suit cela, je pense que mettre la méthode au conditionnel est très bien.

Un code comme celui-ci est inutilement encombré à mon avis:

boolean frobulate_succeeded = thing.frobulate();

if (frobulate_succeeded) {
    ...
}

C'est comme si vous vous répétiez.

Cependant, la question est ambiguë sur la signification de la valeur de retour. Vous dites "un booléen qui indique si l'élément ajouté existait déjà", ce qui pourrait impliquer que true signifie que l'élément existait (et que l'ajout n'a pas eu lieu). Si tel est le cas, je changerais idéalement le comportement de retour de la méthode pour être plus conventionnel. Si ce n'est pas possible, j'ajouterais une variable intermédiaire supplémentaire qui vous permet d'étiqueter clairement le résultat du retour dans votre code (comme suggéré par d'autres).

8
user82096

Je dirais que c'est très semblable à C. La plupart du temps, je préférerais avoir une variable nommée de manière descriptive pour un résultat de mutation, et aucune mutation ne se produisant dans une condition if.

Un compilateur éliminera cette variable si elle est immédiatement réutilisée. Un humain aura plus de facilité à lire la source; pour moi, c'est plus important.

Si quelqu'un doit étendre la condition en ajoutant une clause and/or à la condition if, il se peut qu'il n'appelle pas .add() dans certains cas en raison d'un court-circuit. évaluation. Sauf si un court-circuit est spécifiquement prévu, cela peut devenir un bogue.

2
9000

Votre code semble casser Séparation de requête de commande . Ceci est discuté dans la vidéo Clean Code book et Function Structure . Du point de vue du Clean Code, je pense que ce n'est pas considéré comme un bon style.

"Le code propre est simple et direct. Un code propre se lit comme une prose bien écrite. Un code propre n'obscurcit jamais l'intention du concepteur mais est plutôt plein d'abstractions nettes et de lignes de contrôle simples.

- Grady Booch, auteur d'Analysis Oriented Object and Design with Applications "

Pour moi, l'intention de votre code n'est pas claire. Le si les deux sont-ils exécutés lorsque l'entrée est ajoutée avec succès, ou également lorsqu'elle existe déjà? Que renvoie add()? l'article? Le code d'erreur?

0