Perché usare! Boolean_variable Over boolean_variable == false


60

Un commento a questa domanda: Verifica se un metodo restituisce false: assegnare il risultato alla variabile temporanea o mettere la chiamata del metodo direttamente in condizione? dice che dovresti usare !booleaninvece di boolean == falsequando testare le 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 ci fosse qualche altro motivo per questa preferenza di !boolean?


28
Scrivere è più breve.
Zenon,

39
È come fare boolean == true: non ha senso. Le espressioni dentro le ifdichiarazioni sono proprio questo: espressioni. Se qualcosa valuta già un'espressione booleana, perché dovresti aggiungere un segno di spunta per forzarlo a valutarlo?
Max

10
@zzzzBov: Um, no. Non è così che fanno la maggior parte dei programmatori (stile C).
amara,

9
@zzzzBov: il tuo commento è ambiguo. Se intendevi dire che !boolean_variableè il modo in cui la maggior parte dei programmatori C lo fa, sono d'accordo.
Keith Thompson,

29
E, soprattutto, come mai nessuno vuole scrivere boolean != true?

Risposte:


153

Quando vedo una frase del genere if (!lateForMeeting()), la leggo come "Se non in ritardo per l'incontro" , che è abbastanza semplice da capire, al contrario della if (lateForMeeting() == false)quale avrei letto come "Se il fatto che sono in ritardo per l'incontro è falso " .

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


27
+1 In Python in realtà scrivi if not late_for_meeting:)
phunehehe,

42
Io sostengo che se "se ___ è falso" suona più naturale di "se non ___", allora il nome di ___ deve essere migliorato.
Mike DeSimone,

12
In Perl puoi scrivereunless late_for_meeting
Henrik Ripa il

4
@HenrikRipa: Sembra che quasi tutto ciò che puoi digitare sia un codice legale in Perl. Se fa o meno quello che vuoi è un'altra domanda;)
Adam Robinson,

4
@ A-Cube Non avrei un metodo come quello per cominciare. Invece, avrei un metodo chiamato done(). I doppi negativi sono cattivi.
kba,

97

Scrivere == falseed == trueè ridondante. Può essere portato anche agli 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; ecco a cosa !serve l' operatore ;)


Non ci ho pensato!
ell

51
== falseNON è ridondante, solo più dettagliato di !. OTOH, == trueè ridondante.
dan04,

4
@ dan04 hai ragione. Tuttavia, nel senso in cui lo intendevo, rimane una cattiva idea. Considerare (exp1 != exp2)vs ((exp1 == exp2) == false). Certo, questi sono scenari inventati, ma non dovresti quasi mai scrivere confronti espliciti su vero o falso. Proprio come dovresti usare l'operatore !=, così dovresti usare !.
Andres F.

26
@ dan04: è ridondante quando la lingua offre già !.
DeadMG,

5
@ dan04: ogni volta che scrivi bool_expression == bool_literal, == ...è ridondante. Non importa se stai testando il vero o il falso. È solo un cambiamento nell'ordine dei blocchi conseguenti / alternativi. Gli esempi di Andres illustrano perfettamente questo punto. La maggior parte dei compilatori moderni ottimizzerà la ridondanza, ma è ancora ridondante.
Lèse majesté,

70

In C e in alcuni linguaggi simili, confrontare espressioni booleane per l'uguaglianza falseo trueè un'abitudine pericolosa.

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

Ciò 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 isdigit()funzione dichiarata in <ctype.h>restituisce un intvalore, 0se l'argomento è una cifra, diverso da zero se non lo è. Può tornare 42per indicare che la condizione è vera. Il confronto 42 == truefallirà.

Succede che 0è l'unico valore considerato falso, quindi il confronto per l'uguaglianza falsefunzionerà; if (!cond)e if (cond == false)fare la stessa cosa. Ma se ne trarrai vantaggio, devi ricordare che il confronto con falseè ok e il confronto con truenon lo è. Peggio ancora, il confronto con truefunzionerà per la maggior parte del tempo (ad esempio, l'uguaglianza e gli operatori relazionali producono sempre 0o 1). Ciò significa che qualsiasi bug che introduci usando questo potrebbe essere difficile da rintracciare. (Non preoccuparti, verranno visualizzati non appena avrai demo del codice su un client importante.)

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

Alcune altre lingue hanno ciò che si potrebbe definire booleani meglio educati, in modo tale che cond == truee cond == false(o qualunque sia la sintassi) è sicuro. Anche così, ogni lingua che ho visto ha un operatore noto !; è lì, quindi potresti anche usarlo. L'utilizzo cond == falsepiuttosto che !condo not condnon migliora, secondo me, la leggibilità. (È vero che il !personaggio può essere difficile da vedere a colpo d'occhio; a volte aggiungo uno spazio dopo !per evitarlo.)

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

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

potresti scrivere:

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

Non è sempre meglio, ma non fa male cercare opportunità dove si trova.

Riepilogo: in C e C ++, i confronti tra uguaglianza truee stile falsepericoloso, eccessivamente prolisso e scadente. In molte altre lingue, tali confronti potrebbero non essere pericolosi, ma sono ancora troppo prolissi e di scarsa qualità.


+1 per questa è l'unica risposta con l'effettiva spiegazione tecnica utile.
Mike Nakis,

Continuo a pensare in questo modo, indipendentemente dal linguaggio di programmazione, presumo sempre che == truenon sia sicuro. Si sente meglio così.
Dervall,

1
@Dervall: supponendo che qualcosa che semplicemente non è il caso non vada bene. Ci sono alcuni casi angolari in alcune lingue in cui il confronto di uguaglianza tra i booleani non è solo sicuro ma in realtà appropriato, ad esempio in Haskell, che ha un forte sistema di tipi senza cast implicito con inferenza di tipo bidirezionale, si potrebbe scrivere (==True) . fper chiarire che vogliamo l' -> Boolistanza della funzione polimorfica di ritorno f. È più chiaro di not . not . fe meno imbarazzante di (f :: a -> Bool).
circa il

Inoltre, è certamente appropriato fare cose come pred(x)==pred(y)per una funzione di ritorno bool pred. L'alternativa sarebbe quella pred(x)? pred(y) : !pred(y)che concorderai è difficilmente accettabile.
circa il

1
@leftaroundabout: va bene se lo sai pred(x)e pred(y)usi lo stesso valore per indicare la verità, il che è un presupposto sicuro in alcune lingue ma non in altre. In C, ad esempio, potresti scrivere !!pred(x) == !!pred(y).
Keith Thompson,

14

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

La ragione principale che ho usato == falseè che ho scoperto che !è troppo facile trascurare, quando guardando il codice.

Essendo stato morso severamente da questo, ho preso l'abitudine di renderlo molto chiaro quando testavo per falso.


Se l'operatore fosse stato nominato notcome in Pascal, non credo che questo sarebbe diventato un problema.


5
Proprio per questo motivo, un progetto C ++ su cui ho lavorato per alcuni software per dispositivi medici aveva uno standard di codifica che era obbligatorio == falseinvece che !per lo stesso motivo (per farlo risaltare). Tuttavia, non era necessario utilizzare == truealcun valore, quindi qualsiasi valore diverso da zero funzionava ancora come dovrebbe.
Tcrosley,

12
Ho sempre trovato questo argomento poco convincente - ci sono altri posti in C / C ++ / C # / Java / etc in cui la mancata visualizzazione di un singolo carattere ha un impatto altrettanto significativo sull'interpretazione del codice; individuando "!" come l'unico cattivo non ha senso per me.
Bevan,

5
@bevan Apparentemente non sei ancora stato morso.

1
Anche se concordo sul fatto che trascurare !è probabilmente l'errore più problematico di questo tipo, ciò non dovrebbe far sì che l'IMO non dia l'abitudine di scrivere ==falsema di scrivere test unitari migliori.
circa il

8
@ ThorbjørnRavnAndersen Al contrario - Sono stato morso abbastanza spesso nel corso degli anni che mi sono insegnato a leggere ogni personaggio . Non sono l'autore di tutto (o anche della maggior parte) del codice che devo leggere giorno per giorno, quindi qualsiasi convenzione personale di cui stiamo discutendo qui ha un valore minimo: ho bisogno di capire correttamente tutto il codice che ho letto, non solo le cose che ho scritto.
Bevan,

13

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

Se il sole splende è falso, resto a casa.

Confrontalo con

Se il sole non splende rimango a casa.

Detto questo, concordo sul fatto che il singolo !carattere snello sia facilmente trascurato nel codice. Per questo motivo, preferisco la parola chiave notquando supportata dalla lingua. C ++ per esempio lo consente, sebbene molti programmatori non ne siano consapevoli.

Per le lingue che richiedono !, inserisco uno spazio tra operatore e operando. Questo rende la negazione molto più difficile da trascurare:

if (! condition) { … }

Si noti che ogni programmatore dovrebbe tradurlo automaticamente , senza pensarci due volte, a "non condizionare" nella propria testa. Acquisire questo tipo di fluidità nella lettura di espressioni di codice è tra i primi passi per diventare un buon programmatore.



6

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


Molto tempo fa, quando ho iniziato a programmare, un mio mentore mi ha suggerito di prendere l'abitudine di if( INVALID_HANDLE_VALUE == hFile )evitare cose del genere. In questo modo se scivoli e usi un segno di uguale invece di due, otterrai un errore del compilatore. Ovviamente questo funziona solo quando l'espressione di sinistra è una costante, ma mi ha risparmiato più mal di testa di quanti ne possa contare.
Ha disegnato Chapin il

se usi uno strumento di analisi statica, ti farebbe risparmiare centinaia di volte più mal di testa e sarai in grado di ripristinare la hFile==INVALID_HANDLE_VALUE scrittura naturale .
Gqqnbig,

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. Poiché questa è una logica inversa, è più difficile da capire.


3
! true significa non vero. ! booleano significa non falso o non vero a seconda del valore del booleano, che a sua volta è inversione logica.
S.Robins,

1
@ S.Robins Trovo il nome stupido di booleano per una variabile booleana. Qualcosa come ad esempio isVisiblesarebbe un esempio migliore. Quindi if (!isVisible)significherebbe se non visibile - che è più semplice da capire allora if (isVisible==false), che è una logica inversa. Spero sia più chiaro ora. Oppure ho frainteso il tuo commento?
BЈовић,

2

In (molto) compilatori più vecchi, credo che si spezzerebbero (booleano == falso) in 2 assegnazioni di registro e un codice di confronto in linguaggio macchina. Il primo esempio sarebbe 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 della dimensione del registro da confrontare, rispetto a un invertitore bit a bit (1 clock) e sarebbe più lento da eseguire.

Detto questo, credo che i compilatori più recenti eliminino questo, quindi dovrebbe essere OK andare con entrambi.


Generare codice macchina è il lavoro del compilatore, non del programmatore di alto livello ...
un CVn

Per ragioni storiche, questo potrebbe benissimo essere uno dei motivi per cui un metodo è diventato preferito rispetto all'altro.
Legolas,

1

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

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

perché personalmente sento che la simmetria rende più facile la lettura. Soprattutto se ci sono anche altri booleani in fase di test.

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


4
se value == truequindi non c'è motivo di verificare che non sia nullo. Se value == nullnon dovrebbe mai innescare l'istruzione if in primo luogo, if (value)dovrebbe essere sufficiente.
zzzzBov,

1
I booleani sono oggetti (in Java) e possono quindi essere nulli, quindi solo dire if (value)genera un'eccezione. Lo apprezzerei se le persone che votano in negativo danno una ragione.
WuHo,

3
Mi capita di vederlo, non ho votato. Il null booleano non è una buona pratica. Perché? perché il booleano di solito rappresenta uno stato di qualcosa di acceso o spento. Nella maggior parte dei casi si vorrebbe dichiararlo falso all'inizio e quindi modificarlo insieme al comportamento. È molto raro vedere il booleano non inizializzato.
Melanzana,

Devo essere d'accordo con la melanzana qui, io stesso sono caduto nella cattiva abitudine (specialmente in Java) di lasciare bool non inizializzati e poi finire per controllare nulla. Penso che questo sia più un difetto del linguaggio, tuttavia ciò impone tale difetto all'utente. A mio avviso, quando si dichiara una nuova variabile bool, per impostazione predefinita dovrebbe essere false senza inizializzazione.

2
@WuHoUnited, anche se il valore era null, value == truesarebbe sufficiente.
zzzzBov,

1

Quando stai testando la vera condizione, ha senso fare solo if (condition), specialmente quando applichi la convenzione di denominazione delle variabili booleane che iniziano con 'is': if (isOpen)è perfettamente chiaro e l'uso != falsesarebbe ridondante.

Per un C / C ++ / Java / ecc. programmatore, il significato di "!" l'operatore è completamente assimilato, al punto che abbiamo automaticamente "non" nella nostra mente quando lo vediamo. Quindi avere if (!isOpen)è chiaro come if (_NOT_ isOpen)per me. Ma non hai abbastanza familiarità, in C / C ++ puoi creare una macro #define _NOT_ !. Ma fidati di me, dopo qualche anno è completamente inutile.

A parte questo, è sempre preferibile testare valori booleani senza confrontarli con i valori letterali. Ad esempio, è pericoloso testare if (x == true)perché un valore booleano è considerato vero se non è zero e il vero letterale ha solo un valore specifico, quindi x potrebbe essere "vero" (cioè diverso da zero) e comunque il confronto viene valutato come falso (perché contiene 2 e il vero vero è, diciamo, 1.) Naturalmente questo non si applica a un confronto con falso, ma se non lo usi quando esegui il test per true, perché utilizzarlo quando esegui il test per false?


Non è necessario rendere la macro C ++ che proponi poiché C ++ capisce già 'non'. Correlati: stackoverflow.com/questions/2393673/c-and-or-not-xor-keywords
frozenkoi

È vero, ma è una parola chiave solo per lo standard C ++ 0X. Prima di ciò, era solo un'altra macro.
Fabio Ceconello,

0

Le dimensioni contano ;)

In espressioni miste è più facile leggere:

boolean1 = false
boolean2 = true

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

E soprattutto per il rubino un esempio in cui c'è una grande differenza:

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

zero non è falso, ma non è neppure vero.


0

Sulla base della mia esperienza e delle risposte alla mia domanda a cui hai collegato.

Alcune persone preferiscono usare if (condizione), per il motivo è che è più breve da scrivere. e per me ha davvero 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 vero o falso


0

Se hai chiamato correttamente la tua variabile, allora !booleanè più naturale. Legge not booleanchiunque abbia abbastanza programmatore per leggere il codice mentalmente.


0

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

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

Avere il! (In realtà preferisco un non quando la lingua lo consente) subito l'inglese 'non' per questa condizione lì prima.

Questo problema porta anche alla considerazione dell'uso untilin lingue che lo supportano, ad esempio fare "cose ​​comuni" fino al completamento dell'operazione. Come altri dicono, l'obiettivo è l'espressione del linguaggio naturale. Mi piace l'esempio "il sole splende" sopra.


0

Un altro motivo è che se stai lavorando in una base di codice che utilizza diverse lingue, se c'è un modo idiomatico di fare qualcosa che è sicuro in tutte le lingue, è una buona idea farlo in quel modo ovunque in modo da formare una buona abitudine e hanno meno probabilità di inciampare.

Non riesco a pensare da nessuna parte if (!variable)(o equivalenti come if not variabledipendere dalla tua lingua) non è sicuro, mentre ad es. if self.is_ready() == False: ...Non è sicuro in Python se self.is_ready()ritorna None, ora o in futuro, il che sarebbe una cosa del tutto ragionevole da fare indica che non era pronto poiché Noneè altrettanto falso False.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.