Why Use! boolean_variable Over boolean_variable == false

55

Un commento su questa domanda: Verifica se un metodo restituisce false: assegna risultato alla variabile temporanea, o metti invocazione del metodo direttamente in condizionale? dice che dovresti usare !boolean invece di boolean == false durante il test delle condizioni. Perché? Per me boolean == false è molto più naturale in inglese ed è più esplicito. Mi scuso se questa è solo una questione di stile, ma mi chiedevo se c'era qualche altra ragione per questa preferenza di !boolean ?

    
posta ell 12.04.2017 - 09:31
fonte

16 risposte

148

Quando vedo una riga come if (!lateForMeeting()) , l'ho letto come "Se non è tardi per l'incontro" , che è abbastanza semplice da capire, al contrario di if (lateForMeeting() == false) che I ' d leggere come "Se il fatto che sono in ritardo per incontrarsi è falso" .

Sono identici nel significato, ma il primo è più vicino a come sarebbe costruita la frase inglese equivalente.

    
risposta data 26.02.2012 - 06:13
fonte
96

Scrivere == false e == true è ridondante. Può essere portato anche a estremi arbitrari. Se inizi a scrivere

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

Allora perché no

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

O perché no

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

La morale di questa storia è che se condition è un'espressione booleana, non è necessario aggiungere == false ; questo è l'operatore ! per;)

    
risposta data 25.02.2012 - 22:37
fonte
70

In C e alcune lingue simili, il confronto tra espressioni booleane per l'uguaglianza in false o true è un'abitudine pericolosa.

In C qualsiasi espressione scalare (numerica o puntatore) può essere utilizzata in un contesto booleano, ad esempio come condizione di un'istruzione if . La regola C è che if (cond) è equivalente a if (cond != 0) - vale a dire, zero è falso e qualsiasi valore diverso da zero è vero. Se cond è di tipo puntatore, 0 viene considerato come costante puntatore nullo; if (ptr) significa if (ptr != NULL) .

Questo significa che

if (cond)

e

if (cond == true)

non significa la stessa cosa . Il primo è vero se cond è diverso da zero; il secondo è vero solo se è uguale a true , che in C (se hai #include <stdbool.h> ) è semplicemente 1 .

Ad esempio, la funzione isdigit() dichiarata in <ctype.h> restituisce un valore int , 0 se l'argomento è una cifra, diversa da zero se non lo è. Può restituire 42 per indicare che la condizione è vera. Il confronto con 42 == true fallirà.

Succede che 0 è l'unico valore considerato falso, quindi il confronto tra uguaglianza e false funzionerà; if (!cond) e if (cond == false) fanno la stessa cosa. Ma se hai intenzione di approfittarne, devi ricordare che il confronto con false è ok, e il confronto con true non lo è. Peggio ancora, il confronto con true funzionerà la maggior parte del tempo (ad esempio, l'uguaglianza e gli operatori relazionali producono sempre 0 o 1 ). Ciò significa che eventuali bug introdotti usando questo ancora potrebbero essere difficili da rintracciare. (Non ti preoccupare, appariranno non appena dimostrerai il codice a un cliente importante.)

C ++ ha regole leggermente diverse; ad esempio, il suo tipo bool è un po 'più strettamente integrato nella lingua e if (cond) converte cond nel tipo bool . Ma l'effetto è (principalmente) lo stesso.

Alcuni altri linguaggi hanno quello che si potrebbe definire un booleano con un comportamento migliore, in modo che cond == true e cond == false (o qualsiasi altra cosa la sintassi sia) sia sicuro. Anche così, ogni lingua che ho visto ha un not o ! operatore; è lì, quindi potresti anche usarlo. L'utilizzo di cond == false anziché !cond o not cond non migliora, a mio parere, la leggibilità. (È vero che il carattere ! può essere difficile da vedere a prima vista, a volte aggiungo uno spazio dopo ! per evitare ciò.)

E spesso puoi evitare il problema e migliorare la chiarezza ridisponendo leggermente il codice. Ad esempio, anziché:

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

potresti scrivere:

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

Questo non è sempre migliore, ma non fa male a cercare opportunità dov'è.

Riepilogo: in C e C ++, i confronti di uguaglianza con true e false sono pericolosi, eccessivamente prolissi e di stile scadente. In molte altre lingue, tali confronti potrebbero non essere pericolosi, ma sono ancora eccessivamente prolissi e di stile scadente.

    
risposta data 26.02.2012 - 00:32
fonte
13

Se condition == false è effettivamente "molto più naturale in inglese" per te allora devo presumere che non sei un madrelingua. Altrimenti non posso spiegarlo perché nessuno parla così:

If the sun is shining is false I stay at home.

Confrontalo con

If the sun is not shining I stay at home.

Detto questo, sono d'accordo sul fatto che il singolo, snello ! carattere è facilmente trascurato nel codice. Per questo motivo, preferisco la parola chiave not quando supportata dalla lingua. C ++ per esempio lo consente anche se molti programmatori non ne sono a conoscenza.

Per le lingue che richiedono ! , inserisco uno spazio tra operatore e operando. Ciò rende molto più difficile ignorare la negazione:

if (! condition) { … }

Si noti che ogni programmatore dovrebbe tradurre questo automaticamente , senza pensarci due volte, in "non condizionare" nella propria testa. Acquisire questo tipo di scioltezza nella lettura degli idiomi del codice è tra i primi passi per diventare un buon programmatore.

    
risposta data 27.02.2012 - 02:07
fonte
13

I due sono funzionalmente identici, quindi quale da usare è una questione di gusti.

La ragione principale per cui I uso == false è che ho scoperto che ! è troppo facile da trascurare, quando si guarda al codice.

Essendo stato morso severamente da questo, ho preso l'abitudine di renderlo molto chiaro durante il test per false.

Se l'operatore fosse stato chiamato not come in Pascal, non penso che sarebbe diventato un problema.

    
risposta data 06.03.2012 - 16:19
fonte
7

Quando vedo var == false mi chiedo sempre se var sia booleano o di tipo logico con più di due valori (con, ad esempio, un maybe e un undefined e true e false , o qualcosa come i nove valori di IEEE 1164 ).

    
risposta data 21.11.2012 - 17:54
fonte
6

perché a volte potresti scrivere boolean = false (con gli errori ovvi) e false == boolean non sembra naturale (non importa quanto sia buono di una pratica)

    
risposta data 25.02.2012 - 21:51
fonte
4

if (!boolean_variable) si traduce in if the condition is not true .

if (boolean == false) si traduce in if the condition not false is true . Perché questa è una logica inversa, è più difficile da capire.

    
risposta data 26.02.2012 - 12:56
fonte
2

In (molto) vecchi compilatori, credo che si rompono (booleano == falso) in 2 assegnazioni di registro e un codice di confronto in linguaggio macchina. Il primo esempio verrebbe suddiviso in un compito e un operatore NOT. In termini di prestazioni, l'operazione di confronto richiederebbe un numero di cicli di clock, a seconda delle dimensioni del registro da confrontare, rispetto a un'inversione bit a bit (1 clock) e sarebbe più lenta da eseguire.

Detto questo, credo che i compilatori più recenti possano farla franca, quindi dovrebbe andare bene con entrambi.

    
risposta data 26.02.2012 - 05:39
fonte
1

Al lavoro ho spesso a che fare con booleani che possono essere nulli quindi codecerò spesso questo caso come

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

perché personalmente ritengo che la simmetria faciliti la lettura. Soprattutto se ci sono altri Booleani in fase di test.

Non mi interessa davvero in un modo o nell'altro.

    
risposta data 25.02.2012 - 21:52
fonte
1

Quando stai testando la condizione vera, ha senso fare solo if (condition) , specialmente quando applichi la convenzione di denominare le variabili booleane che iniziano con 'is': if (isOpen) è perfettamente chiaro e usando != false sarebbe essere ridondante.

Per un C / C ++ / Java / ecc. programmatore, il significato del '!' l'operatore è completamente assimilato, al punto che automaticamente non abbiamo "nella nostra mente" quando lo vediamo. Quindi avere if (!isOpen) è chiaro come if (_NOT_ isOpen) per me. Ma non sei abbastanza familiare, in C / C ++ potresti creare una macro con #define _NOT_ ! . Ma credimi, dopo alcuni anni questo non è assolutamente necessario.

A parte questo, è sempre preferibile testare valori booleani senza confrontarli con letterali. Ad esempio, è pericoloso testare if (x == true) perché un valore booleano è considerato vero se non è zero, e il valore letterale ha solo un valore specifico, quindi x potrebbe essere 'vero' (cioè diverso da zero) e il confronto deve essere valutato su falso (poiché contiene 2 e il letterale true è, ad esempio, 1.) Ovviamente ciò non si applica a un confronto con false, ma se non lo si utilizza quando si esegue il test di true, perché utilizzarlo quando si esegue il test di false?

    
risposta data 25.02.2012 - 23:16
fonte
0

Le dimensioni contano;)

Nelle espressioni miste è più facile da leggere:

boolean1 = false
boolean2 = true

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

E in particolare per ruby un esempio in cui è una grande differenza:

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

nil non è falso, ma non è nemmeno vero.

    
risposta data 25.02.2012 - 22:09
fonte
0

In base alla mia esperienza e alle risposte del mio quesion a cui ti sei collegato.

Alcune persone preferiscono usare se (condizione), perché la ragione è quella che è più breve da scrivere. e per me ha effettivamente senso, ad esempio (! isValidated ()) Ho letto questo come non convalidato. ma per me è tutto basato sulle preferenze personali e dipende dalla struttura logica del metodo isValidated (), se restituisce true o false

    
risposta data 26.02.2012 - 07:47
fonte
0

Se hai chiamato correttamente la tua variabile, !boolean è più naturale. Legge come not boolean a chiunque sia abbastanza di un programmatore per leggere il codice mentalmente.

    
risposta data 26.02.2012 - 14:02
fonte
0

Per alcune persone, prima viene espresso un significato, meglio è.

Per quelli che hanno "se! ..." si confrontano più velocemente con "se ...", quindi devono leggere l'intera condizione (che potrebbe essere effettivamente piuttosto lunga, ad esempio (thisThing = thatThing o qualcosa = l'altra cosa ) OR (thinga = thingb e thinga = thingd), ecc.) Solo per trovare il == false alla fine.

Avere il! (Io in realtà preferisco non quando la lingua lo consente) proprio davanti a te l'inglese non 'per' questa condizione in là prima.

Questo problema porta anche a considerare l'utilizzo di until nelle lingue che lo supportano, ad es. fai 'cose comuni' fino a quando la cosa non finisce. Come altri dicono, l'espressione del linguaggio naturale è l'obiettivo. Mi piace l'esempio "sole splende" sopra.

    
risposta data 27.02.2012 - 05:53
fonte
0

Un altro motivo è che se stai lavorando in un codebase che usa diverse lingue, se c'è un modo idiomatico di fare qualcosa che è sicuro in tutte le lingue, è una buona idea farlo in quel modo dappertutto così da formare una buona abitudine e meno probabilità di inciampare.

Non riesco a pensare a nessuna parte che if (!variable) (o equivalenti come if not variable a seconda della tua lingua) non sia sicuro, mentre ad es. if self.is_ready() == False: ... non è sicuro in python se self.is_ready() restituisce None , ora o in futuro, il che sarebbe una cosa assolutamente ragionevole da fare per indicare che non era pronto poiché None è altrettanto falsa di False .

    
risposta data 08.10.2018 - 15:32
fonte

Leggi altre domande sui tag