web-dev-qa-db-fra.com

Pourquoi utiliser! Boolean_variable sur boolean_variable == false

Un commentaire sur cette question: Vérifier si une méthode retourne false: attribuer le résultat à une variable temporaire, ou mettre l'invocation de méthode directement au conditionnel? dit que vous devez utiliser !boolean au lieu de boolean == false lors du test des conditions. Pourquoi? Tome boolean == false est beaucoup plus naturel en anglais et plus explicite. Je m'excuse si c'est juste une question de style, mais je me demandais s'il y avait une autre raison pour cette préférence de !boolean?

62
ell

Quand je vois une ligne comme if (!lateForMeeting()), je la lis comme "Si ce n'est pas en retard pour la réunion", ce qui est assez simple à comprendre, par opposition à if (lateForMeeting() == false) que je lirais comme "Si le fait que je suis en retard pour une réunion est faux".

Ils ont un sens identique, mais le premier est plus proche de la façon dont la phrase anglaise équivalente serait construite.

158
kba

L'écriture == false et == true est redondant. Il peut également être amené à des extrêmes arbitraires. Si vous commencez à écrire

if (condition == false) { ... }

Alors pourquoi pas

if ((condition == false) == true) { ... }

Ou pourquoi pas

if ((someExp == anotherExp) == true) { ... }

La morale de cette histoire est que si condition est une expression booléenne, vous n'avez pas besoin d'ajouter == false; c'est ce que l'opérateur ! est pour ;)

99
Andres F.

En C et dans certains langages similaires, comparer les expressions booléennes pour l'égalité à false ou true est une habitude dangereuse.

En C, toute expression scalaire (numérique ou pointeur) peut être utilisée dans un contexte booléen, par exemple comme condition d'une instruction if. La règle C est que if (cond) est équivalent à if (cond != 0) - c'est-à-dire que zéro est faux et tout une valeur non nulle est vraie. Si cond est de type pointeur, 0 Est traité comme une constante pointeur nul; if (ptr) signifie if (ptr != NULL).

Cela signifie que

if (cond)

et

if (cond == true)

ne signifie pas la même chose . Le premier est vrai si cond est différent de zéro; la seconde n'est vraie que si elle est égale à true, qui en C (si vous avez #include <stdbool.h>) est simplement 1.

Par exemple, la fonction isdigit() déclarée dans <ctype.h> Renvoie une valeur int, 0 Si l'argument est un chiffre, différent de zéro s'il ne l'est pas ' t. Il peut retourner 42 Pour indiquer que la condition est vraie. La comparaison de 42 == true Échouera.

Il arrive que 0 Soit la seule valeur considérée comme fausse, donc la comparaison pour l'égalité avec false fonctionnera; if (!cond) et if (cond == false) font la même chose. Mais si vous voulez en profiter, vous devez vous rappeler que la comparaison avec false est acceptable, et la comparaison avec true ne l'est pas. Pire encore, la comparaison avec true fonctionnera la plupart du temps (par exemple, les opérateurs d'égalité et relationnels produisent toujours soit 0 Ou 1). Cela signifie que tout bogue que vous introduisez en l'utilisant peut être difficile à localiser. (Ne vous inquiétez pas, ils apparaîtront dès que vous démontrez le code à un client important.)

C++ a des règles légèrement différentes; par exemple, son type bool est un peu plus étroitement intégré dans le langage, et if (cond) convertit cond en type bool. Mais l'effet est (principalement) le même.

Certaines autres langues ont ce que l'on pourrait appeler des booléens mieux comportés, tels que cond == true Et cond == false (Ou quelle que soit la syntaxe) est sûr. Même ainsi, chaque langue que j'ai vue a un opérateur not ou !; il est là, vous pouvez donc aussi bien l'utiliser. Utiliser cond == false Plutôt que !cond Ou not cond N'améliore pas, à mon avis, la lisibilité. (Il est vrai que le caractère ! Peut être difficile à voir d'un coup d'œil; j'ajoute parfois un espace après le ! Pour éviter cela.)

Et souvent, vous pouvez éviter le problème et améliorer la clarté en réorganisant légèrement le code. Par exemple, plutôt que:

if (!cond) {
    do_this();
}
else {
    do_that();
}

vous pourriez écrire:

if (cond) {
    do_that();
}
else {
    do_this();
}

Ce n'est pas toujours meilleur, mais cela ne fait pas de mal de chercher des opportunités là où elles se trouvent.

Résumé: En C et C++, les comparaisons d'égalité avec true et false sont dangereuses, trop verbeuses et de mauvais style. Dans de nombreuses autres langues, de telles comparaisons peuvent ne pas être dangereuses, mais elles sont toujours trop bavardes et de mauvais style.

74
Keith Thompson

Les deux sont fonctionnellement identiques, celui à utiliser est donc une question de goût.

La principale raison pour laquelle I utilise == false c'est que j'ai trouvé que !est trop facile à ignorer quand on regarde le code.

Ayant été sévèrement mordu par cela, j'ai pris l'habitude de le dire très clairement lors des tests de faux.


Si l'opérateur avait été nommé not comme en Pascal, je ne pense pas que cela serait devenu un problème.

14
user1249

Si condition == false est en effet "beaucoup plus naturel en anglais" pour vous alors je dois supposer que vous n'êtes pas natif. Sinon, je ne peux pas l'expliquer, car personne parle comme ça:

Si le soleil brille, c'est faux je reste chez moi.

Comparez cela à

Si le soleil ne brille pas, je reste chez moi.

Cela dit, je conviens que le single, mince ! le caractère est facilement ignoré dans le code. Pour cette raison, je préfère le mot clé not lorsqu'il est pris en charge par la langue. C++ par exemple ne permet cela bien que de nombreux programmeurs n'en soient pas conscients.

Pour les langues qui nécessitent !, Je mets un espace entre opérateur et opérande. Cela rend la négation beaucoup plus difficile à ignorer:

if (! condition) { … }

Notez que chaque programmeur devrait traduire cela automatiquement, sans y penser, "ne pas conditionner" dans sa tête. Acquérir ce type de maîtrise de la lecture des idiomes de code est parmi les premières étapes pour devenir un bon programmeur.

13
Konrad Rudolph

parce que parfois vous pourriez écrire boolean = false (avec les erreurs évidentes) et false == boolean ne semble pas naturel (peu importe la qualité d'une pratique)

7
ratchet freak

Quand je vois var == false Je me demande toujours si var est booléen ou de type logique avec plus de deux valeurs (avec, par exemple, un maybe et un undefined ainsi que true et false, ou quelque chose comme les neuf valeurs de IEEE 1164 ).

7
AProgrammer

if (!boolean_variable) se traduit par if the condition is not true.

if (boolean == false) se traduit par if the condition not false is true. Parce que c'est une logique inversée, c'est plus difficile à comprendre.

4
BЈовић

Dans les compilateurs (beaucoup) plus anciens, je pense qu'ils diviseraient (booléen == faux) en 2 affectations de registre et un code de comparaison en langage machine. Le premier exemple serait divisé en une affectation et un opérateur NOT. En termes de performances, l'opération de comparaison prendrait un certain nombre de cycles d'horloge, selon la taille du registre comparé, par rapport à un inverseur au niveau du bit (1 horloge) et serait plus lente à exécuter.

Cela étant dit, je crois que les nouveaux compilateurs suppriment cela, donc ça devrait aller avec l'un ou l'autre.

2
lcllam

Lorsque vous testez la vraie condition, il est logique de ne faire que if (condition), en particulier lorsque vous appliquez la convention de nommage des variables booléennes commençant par 'is': if (isOpen) est parfaitement clair et l'utilisation de != false serait redondante.

Pour un C/C++/Java/etc. programmeur, la signification du '!' L'opérateur est complètement assimilé, au point que nous avons automatiquement "non" dans notre esprit quand nous le voyons. Donc, avoir if (!isOpen) est aussi clair que if (_NOT_ isOpen) pour moi. Mais vous n'êtes pas assez familier, en C/C++ vous pouvez créer une macro avec #define _NOT_ !. Mais croyez-moi, après quelques années, cela est complètement inutile.

En dehors de cela, il est toujours préférable de tester les valeurs booléennes sans les comparer avec des littéraux. Par exemple, il est dangereux de tester if (x == true) car une valeur booléenne est considérée comme vraie si elle n'est pas nulle, et le littéral vrai n'a qu'une seule valeur spécifique, donc x pourrait être "vrai" (c'est-à-dire non nul) et toujours le la comparaison est évaluée à faux (car elle contient 2 et le vrai littéral est, disons, 1.) Bien sûr, cela ne s'applique pas à une comparaison avec faux, mais si vous ne l'utilisez pas lorsque vous testez vrai, pourquoi l'utiliser quand test de faux?

1
Fabio Ceconello

Basé sur mon expérience et les réponses de ma question à laquelle vous avez lié.

Certaines personnes préfèrent utiliser if (condition), car cela est plus court à écrire. et pour moi, cela a du sens, par exemple (! isValidated ()) J'ai lu ceci comme non validé. mais pour moi, tout est basé sur les préférences personnelles, et cela dépend de la structure logique de la méthode isValidated (), si elle retourne vrai ou faux

0
KyelJmD

Si vous avez correctement nommé votre variable, alors !boolean est plus naturel. Il se lit comme not boolean à tous ceux qui sont assez programmeurs pour lire le code mentalement.

Pour certaines personnes, plus tôt un sens est exprimé, mieux c'est.

Pour ces gens qui ont "si! ..." se compare plus rapidement à "si ...", alors avoir à lire l'intégralité de la condition (qui pourrait en fait être assez longue, par exemple (thisThing = thatThing ou quelque chose = l'autre chose) OR (thinga = thingb et thinga = thingd), etc.) juste pour trouver le == faux à la fin.

Avoir le! (Je préfère en fait un pas quand la langue le permet) dès le début obtient l'anglais "non" pour cette condition plus tôt.

Ce problème conduit également à envisager l'utilisation de until dans les langues qui le prennent en charge, par exemple faire des "trucs communs" jusqu'à ce que la chose soit terminée. Comme d'autres le disent, l'expression du langage naturel est le but. J'aime l'exemple "Le soleil brille" ci-dessus.

0
junky

Au travail, j'ai souvent affaire à des booléens qui peuvent être nuls, donc je code souvent ce cas comme

if (value != null && value == true) {
        //do something
}

parce que je pense personnellement que la symétrie facilite la lecture. Surtout si d'autres booléens sont également testés.

Je m'en fiche vraiment d'une façon ou d'une autre.

0
WuHoUnited

Questions de taille ;)

Dans les expressions mixtes, il est plus facile de lire:

boolean1 = false
boolean2 = true

p ! boolean1 and ! boolean2
p boolean1 == false and boolean2 == false

Et surtout pour Ruby un exemple où c'est une grande différence:

boolean = nil
p ! boolean         #-> true
p boolean == false  #-> false

nul n'est pas faux, mais ce n'est pas vrai non plus.

0
knut

Une autre raison est que si vous travaillez dans une base de code qui utilise plusieurs langues, s'il existe une façon idiomatique de faire quelque chose qui est sûr dans toutes les langues, c'est une assez bonne idée de le faire de cette façon partout afin de former une bonne habitude. et sont moins susceptibles de trébucher.

Je ne peux penser à aucun endroit où if (!variable) (ou des équivalents tels que if not variable Selon votre langue) n'est pas sûr, alors que par ex. if self.is_ready() == False: ... n'est pas sûr dans python si self.is_ready() renvoie None, maintenant ou à l'avenir, ce qui serait tout à fait raisonnable pour qu'il indique qu'il n'était pas prêt puisque None est tout aussi falsey que False.

0
daphtdazz