Gründe für die Verwendung von! Boolean_variable Über boolean_variable == false

59

Ein Kommentar zu dieser Frage: Prüfen, ob eine Methode false zurückgibt: Ergebnis temporärer Variable zuweisen oder Methodenaufruf direkt in Bedingung setzen? sagt , dass Sie verwenden sollten , !booleanstatt boolean == falsebei der Prüfung Bedingungen. Warum? Für mich boolean == falseist Englisch viel natürlicher und expliziter. Ich entschuldige mich, wenn dies nur eine Frage des Stils ist, aber ich habe mich gefragt, ob es einen anderen Grund für diese Präferenz von !boolean?

ell
quelle
28
Es ist kürzer zu schreiben.
Zenon
39
Es ist so, als würde man es tun boolean == true: Es ergibt keinen Sinn. Ausdrücke in ifAnweisungen sind genau das: Ausdrücke. Wenn etwas bereits zu einem booleschen Ausdruck ausgewertet wird, warum sollten Sie ein Häkchen hinzufügen, um es dazu zu zwingen, dies zu bewerten?
Maxpm
10
@zzzzBov: Ähm, nein. So machen es die meisten (C-artigen) Programmierer nicht.
Amara
9
@zzzzBov: Ihr Kommentar ist mehrdeutig. Wenn Sie das so gemeint haben, wie !boolean_variablees die meisten C-Programmierer tun, stimme ich zu.
Keith Thompson
29
Und was noch wichtiger ist, warum will niemand schreiben boolean != true?

Antworten:

153

Wenn ich eine Zeile sehen wie if (!lateForMeeting()), las ich , dass wie „Wenn nicht zu spät für ein Treffen“ , die ziemlich geradlinig ist , zu verstehen, im Gegensatz zu , if (lateForMeeting() == false)die ich gelesen habe , wie „Wenn die Tatsache , dass ich zu spät zum Treffen bin falsch ist " .

Ihre Bedeutung ist identisch, aber erstere entspricht eher der Konstruktion des entsprechenden englischen Satzes.

kba
quelle
27
+1 In Python schreibst du tatsächlich if not late_for_meeting:)
phunehehe
42
Ich behaupte, wenn "wenn ___ falsch ist" natürlicher klingt als "wenn nicht ___", dann muss der Name von ___ verbessert werden.
Mike DeSimone
12
In Perl können Sie schreibenunless late_for_meeting
Henrik Ripa
4
@HenrikRipa: Es scheint, als ob fast alles, was Sie eingeben können, legaler Code in Perl ist. Ob es tut, was Sie wollen, ist eine andere Frage;)
Adam Robinson
4
@ A-Cube Eine solche Methode hätte ich zunächst nicht. Stattdessen hätte ich eine Methode namens done(). Doppelte Negative sind schlecht.
kba
97

Schreiben == falseund == trueist überflüssig. Es kann auch zu willkürlichen Extremen geführt werden. Wenn Sie anfangen zu schreiben

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

Warum dann nicht?

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

Oder warum nicht?

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

Die Moral dieser Geschichte lautet: Wenn conditiones sich um einen booleschen Ausdruck handelt, brauchen Sie nichts hinzuzufügen == false. dafür ist der operator da !;)

Andres F.
quelle
Daran habe ich nicht gedacht!
Ell
51
== falseist NICHT redundant, nur ausführlicher als !. OTOH == trueist überflüssig.
25.
4
@ dan04 Du hast recht. In dem Sinne, wie ich es gemeint habe, bleibt es jedoch eine schlechte Idee. Betrachten (exp1 != exp2)vs ((exp1 == exp2) == false). Zugegeben, dies sind erfundene Szenarien, aber Sie sollten dennoch fast nie explizite Vergleiche mit wahr oder falsch anstellen. So wie Sie operator verwenden sollten !=, sollten Sie auch operator verwenden !.
Andres F.
26
@ dan04: Es ist überflüssig, wenn die Sprache schon bietet !.
DeadMG
5
@ dan04: Immer wenn du schreibst bool_expression == bool_literal, == ...ist das überflüssig. Ob Sie auf Richtig oder Falsch prüfen, ist unerheblich. Es ist nur eine Änderung in der Reihenfolge der nachfolgenden / alternativen Blöcke. Andres Beispiele veranschaulichen diesen Punkt perfekt. Die meisten modernen Compiler optimieren die Redundanz, aber sie ist immer noch redundant.
Majestätsbeleidigung
70

In C und einigen ähnlichen Sprachen, zu vergleichen Booleschen Ausdrücken auf Gleichheit falseoder trueist eine gefährliche Gewohnheit.

In C kann jeder skalare Ausdruck (numerisch oder Zeiger) in einem booleschen Kontext verwendet werden, beispielsweise als Bedingung einer ifAnweisung. Die C-Regel ist if (cond)äquivalent zu if (cond != 0)- dh Null ist falsch und jeder Wert ungleich Null ist wahr. Wenn condes vom Zeigertyp ist, 0wird es als Nullzeiger-Konstante behandelt. if (ptr)bedeutet if (ptr != NULL).

Das bedeutet, dass

if (cond)

und

if (cond == true)

meine nicht dasselbe . Das erste ist wahr, wenn condes nicht Null ist; die zweite ist nur dann wahr, wenn sie gleich ist true, was in C (wenn Sie haben #include <stdbool.h>) einfach ist 1.

Beispielsweise gibt die in isdigit()deklarierte Funktion <ctype.h>einen intWert zurück, 0wenn das Argument eine Ziffer ist, und nicht Null, wenn dies nicht der Fall ist. Es kann zurückkehren, 42um anzuzeigen, dass die Bedingung erfüllt ist. Der Vergleich 42 == truewird fehlschlagen.

Es kommt vor, dass dies 0der einzige Wert ist, der als falsch eingestuft falsewird. if (!cond)und if (cond == false)mache dasselbe. Aber wenn Sie das ausnutzen wollen, müssen Sie sich daran erinnern, dass Vergleichen mit falsein Ordnung ist und Vergleichen mit truenicht. Schlimmer noch, der Vergleich mit truewird die meiste Zeit funktionieren (zum Beispiel ergeben die Gleichheits- und Vergleichsoperatoren immer entweder 0oder 1). Dies bedeutet, dass es schwierig sein kann, alle Fehler aufzuspüren, die Sie hiermit einführen. (Keine Sorge, sie werden angezeigt, sobald Sie einem wichtigen Kunden den Code vorführen.)

C ++ hat etwas andere Regeln; Beispielsweise ist sein boolTyp etwas enger in die Sprache integriert und if (cond)wird condin Typ konvertiert bool. Aber der Effekt ist (meistens) der gleiche.

Einige andere Sprachen haben so etwas wie besser benommene Boolesche Sprachen, dass cond == trueund cond == false(oder wie auch immer die Syntax lautet) sicher sind. Trotzdem hat jede Sprache, die ich gesehen habe, einen Operator notoder !. es ist da, also kannst du es genauso gut benutzen. Verwenden cond == falsestatt !condoder not condnicht, meiner Meinung nach , zur Verbesserung der Lesbarkeit. (Es ist wahr, dass die !Figur auf einen Blick schwer zu erkennen ist. Manchmal füge ich nach dem ein Leerzeichen hinzu !, um dies zu vermeiden.)

Und oft können Sie das Problem vermeiden und die Übersichtlichkeit verbessern, indem Sie den Code leicht neu anordnen. Zum Beispiel anstatt:

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

du könntest schreiben:

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

Das ist nicht immer besser, aber es tut nicht weh, nach Möglichkeiten zu suchen, wo es ist.

Zusammenfassung: In C und C ++, Gleichheit Vergleichen trueund falseist gefährlich, allzu ausführlich, und schlechter Stil. In vielen anderen Sprachen sind solche Vergleiche vielleicht nicht gefährlich, aber sie sind immer noch zu ausführlich und von schlechtem Stil.

Keith Thompson
quelle
+1 dafür ist die eine Antwort mit der tatsächlich nützlichen technischen Erklärung.
Mike Nakis
Ich denke immer noch so, unabhängig von der Programmiersprache, ich gehe immer davon aus, dass == truedas unsicher ist. Fühlt sich so besser an.
Dervall
1
@Dervall: Etwas anzunehmen, das einfach nicht der Fall ist, ist auch nicht gut. Es gibt ein paar Sonderfälle in bestimmten Sprachen , in denen Gleichheitsvergleich von booleans nicht nur sicher ist , sondern in der Tat angezeigt, zum Beispiel in Haskell, die ein starkes impliziten Guss freier Typen System mit bidirektionaler Typinferenz hat, könnte man schreiben (==True) . fklarstellen, dass wir wollen die -> Boolinstanziierung der return-polymorphen funktion f. Das ist klarer als not . not . fund weniger umständlich als (f :: a -> Bool).
links ungefähr
Außerdem ist es durchaus angebracht, pred(x)==pred(y)Dinge zu tun, wie zum Beispiel eine Bool-Return-Funktion pred. Die Alternative, pred(x)? pred(y) : !pred(y)der Sie zustimmen werden, ist kaum akzeptabel.
linksum den
1
@leftaroundabout: Das ist in Ordnung, wenn Sie das wissen pred(x)und pred(y)denselben Wert verwenden, um die Wahrheit zu bezeichnen, was in einigen Sprachen eine sichere Annahme ist, in anderen jedoch nicht. In C könnten Sie beispielsweise schreiben !!pred(x) == !!pred(y).
Keith Thompson
13

Wenn condition == falsees für Sie in der Tat "viel natürlicher in Englisch" ist, dann muss ich davon ausgehen, dass Sie kein Muttersprachler sind. Ansonsten kann ich das nicht erklären, weil niemand so spricht:

Wenn die Sonne scheint, ist falsch, ich bleibe zu Hause.

Vergleichen Sie das mit

Wenn die Sonne nicht scheint, bleibe ich zu Hause.

Trotzdem stimme ich zu, dass das einzelne, schlanke !Zeichen im Code leicht übersehen wird. Aus diesem Grund bevorzuge ich das Schlüsselwort, notwenn es von der Sprache unterstützt wird. C ++ zum Beispiel tut dies erlauben , obwohl viele Programmierer davon nicht bewusst sind.

Für Sprachen, die es erfordern !, setze ich ein Leerzeichen zwischen Operator und Operand. Dies macht die Verneinung viel schwerer zu übersehen:

if (! condition) { … }

Beachten Sie, dass jeder Programmierer dies automatisch und ohne Bedenken so übersetzen sollte , dass es nicht im Kopf vorkommt. Das Erlernen dieser fließenden Kenntnisse beim Lesen von Code-Idiomen ist einer der ersten Schritte, um ein guter Programmierer zu werden.

Konrad Rudolph
quelle
13

Die beiden sind funktional identisch, so dass es Geschmackssache ist, welche man verwendet.

Der Hauptgrund, den ich benutze, == falseist, dass ich festgestellt habe, dass dies !beim Betrachten von Code zu leicht zu übersehen ist.

Ich habe es mir zur Gewohnheit gemacht, dies beim Testen auf Falsch sehr deutlich zu machen.


Wäre der Operator notwie in Pascal benannt worden, wäre dies meines Erachtens kein Problem geworden.

user1249
quelle
5
Aus genau diesem Grund hatte ein C ++ - Projekt, an dem ich für eine Medizinproduktesoftware gearbeitet habe, einen Kodierungsstandard, der == falseanstelle !desselben vorgeschrieben war (um ihn hervorzuheben). Es war jedoch nicht erforderlich == true, einen anderen Wert als Null zu verwenden.
Tcrosley
12
Ich fand dieses Argument immer nicht überzeugend - es gibt andere Stellen in C / C ++ / C # / Java / etc, an denen das Nichtvorhandensein eines einzelnen Zeichens einen ähnlich bedeutenden Einfluss auf die Interpretation des Codes hat. Aussonderung "!" als der einzig schlechte ergibt das für mich keinen sinn.
Bevan
5
@bevan Anscheinend bist du noch nicht gebissen worden.
1
Obwohl ich der Meinung bin, dass das Übersehen der !wahrscheinlich lästigste Fehler dieser Art ist, sollte dies IMO nicht dazu führen, dass man sich angewöhnt, zu schreiben, ==falsesondern bessere Komponententests zu schreiben.
links ungefähr
8
@ ThorbjørnRavnAndersen Ganz im Gegenteil - ich bin im Laufe der Jahre oft genug gebissen worden, dass ich mir selbst beigebracht habe, jeden Charakter zu lesen . Ich bin nicht der Autor des gesamten (oder sogar des größten Teils) Codes, den ich täglich lesen muss. Daher hat jede persönliche Konvention, die wir hier diskutieren, nur einen minimalen Wert: Ich muss den gesamten Code, den ich lese, richtig verstehen , nicht nur das Zeug, das ich geschrieben habe.
Bevan,
7

Wenn ich sehe, var == falsefrage ich mich immer, ob vares sich um einen Booleschen Wert oder einen Logiktyp mit mehr als zwei Werten handelt (z. B. mit einem maybeund einem undefinedsowie trueund falseoder so etwas wie den neun Werten von IEEE 1164 ).

AProgrammer
quelle
8
Der dritte Wert ist normalerweise "Datei nicht gefunden". thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
Groky
6

weil manchmal Sie schreiben könnten boolean = false(mit den offensichtlichen Fehlern) und false == booleannicht natürlich scheinen (egal wie gut eine Praxis ist)

Ratschenfreak
quelle
Vor langer Zeit, als ich anfing zu programmieren, meinte ein Mentor, ich würde es mir zur Gewohnheit machen if( INVALID_HANDLE_VALUE == hFile ), solche Dinge zu vermeiden. Auf diese Weise erhalten Sie einen Compilerfehler, wenn Sie ein Gleichheitszeichen anstelle von zwei verwenden. Das funktioniert natürlich nur, wenn der linke Ausdruck eine Konstante ist, aber es hat mir mehr Kopfschmerzen erspart, als ich zählen kann.
Drew Chapin
Wenn Sie ein statisches Analysewerkzeug verwenden, sparen Sie hundertmal mehr Kopfschmerzen und können das Naturschreiben wiederherstellen hFile==INVALID_HANDLE_VALUE .
Gqqnbig
4

if (!boolean_variable)übersetzt zu if the condition is not true.

if (boolean == false)übersetzt zu if the condition not false is true. Da dies umgekehrte Logik ist, ist es schwieriger zu verstehen.

BЈовић
quelle
3
! true bedeutet nicht true. ! boolean bedeutet entweder nicht falsch oder nicht wahr, abhängig vom Wert des Booleschen Werts, der selbst eine logische Inversion ist.
S.Robins
1
@ S.Robins Ich finde den blöden Namen von Boolean für eine Boolean-Variable. So etwas wie zum Beispiel isVisiblewäre ein besseres Beispiel. Dann if (!isVisible)würde bedeuten, wenn nicht sichtbar - was dann einfacher zu verstehen ist if (isVisible==false), was eine inverse Logik ist. Hoffe es ist jetzt klarer. Oder habe ich Ihren Kommentar falsch verstanden?
BЈовић
2

In (viel) älteren Compilern, glaube ich, würden sie (boolean == false) in 2 Registerzuweisungen und einen Vergleichscode in Maschinensprache aufteilen. Das erste Beispiel würde in eine Zuweisung und einen NOT-Operator aufgeteilt. In Bezug auf die Leistung würde die Vergleichsoperation abhängig von der Größe des zu vergleichenden Registers eine Anzahl von Taktzyklen in Anspruch nehmen, verglichen mit einer bitweisen Invertierung (1 Takt) und wäre langsamer auszuführen.

Davon abgesehen glaube ich, dass neuere Compiler dies abschaffen, daher sollte es auch in Ordnung sein, damit umzugehen.

lcllam
quelle
Das Generieren von Maschinencode ist Aufgabe des Compilers, nicht der Programmierer ...
ein CVn
Aus historischen Gründen kann dies durchaus einer der Gründe sein, warum eine Methode der anderen vorgezogen wurde.
Legolas
1

Bei der Arbeit habe ich es oft mit Booleschen Werten zu tun, die null sein können. Daher codiere ich diesen Fall oft als

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

weil ich persönlich der Meinung bin, dass die Symmetrie das Lesen erleichtert. Vor allem, wenn auch andere Boolesche Werte getestet werden.

Es ist mir so oder so egal.

WuHoUnited
quelle
4
wenn value == truedann gibt es keinen Grund zu prüfen, dass es nicht null ist. Sollte die value == nullif-Anweisung niemals ausgelöst werden, if (value)sollte dies ausreichen.
zzzzBov
1
Boolesche Werte sind Objekte (in Java) und können daher null sein, um nur zu sagen, dass sie if (value)eine Ausnahme auslösen . Ich würde es begrüßen, wenn Leute, die abstimmen, einen Grund angeben.
WuHoUnited
3
Ich habe das einfach zufällig gesehen, habe nicht abgelehnt. Boolescher Nullwert ist keine gute Praxis. Warum? weil boolean normalerweise einen Zustand von etwas darstellt, das ein- oder ausgeschaltet ist. In den meisten Fällen möchten Sie es am Anfang für falsch erklären und dann zusammen mit dem Verhalten ändern. Es kommt sehr selten vor, dass Boolesche Werte nicht initialisiert werden.
Aubergine
Ich muss Aubergine hier zustimmen, ich selbst habe die schlechte Angewohnheit (besonders in Java), Bools nicht initialisiert zu lassen und dann nach null zu suchen. Ich denke, dies ist eher ein Sprachfehler, der dem Benutzer jedoch diesen Fehler auferlegt. Wenn eine neue bool-Variable deklariert wird, sollte sie meiner Meinung nach standardmäßig false ohne Initialisierung sein.
2
@WuHoUnited value == truewürde ausreichen , selbst wenn der Wert null wäre.
zzzzBov
1

Wenn Sie die wahre Bedingung testen, ist es sinnvoll, dies zu tun if (condition), insbesondere, wenn Sie die Konvention anwenden, dass boolesche Variablen mit 'is' beginnen: if (isOpen)ist völlig klar und die Verwendung != falsewäre überflüssig.

Für ein C / C ++ / Java / etc. Programmierer, die Bedeutung des '!' Der Operator ist vollständig assimiliert, bis zu dem Punkt, dass wir automatisch "nicht" im Kopf haben, wenn wir es sehen. So ist das Haben if (!isOpen)so klar wie if (_NOT_ isOpen)für mich. Aber Sie sind nicht vertraut genug, in C / C ++ könnten Sie ein Makro mit erstellen #define _NOT_ !. Aber glauben Sie mir, nach ein paar Jahren ist das völlig unnötig.

Abgesehen davon ist es immer vorzuziehen, Boolesche Werte zu testen, ohne sie mit Literalen zu vergleichen. Zum Beispiel ist es gefährlich zu testen, if (x == true)weil ein boolescher Wert als wahr betrachtet wird, wenn er nicht null ist, und das Literal wahr nur einen bestimmten Wert hat, so dass x "wahr" (dh ungleich null) sein kann und der Vergleich dennoch als falsch ausgewertet wird (weil es wahr ist) enthält 2 und das wörtliche true ist beispielsweise 1.) Natürlich gilt das nicht für einen Vergleich mit false, aber wenn Sie es beim Testen auf true nicht verwenden, warum dann, wenn Sie es auf false testen?

Fabio Ceconello
quelle
Es ist nicht erforderlich, das von Ihnen vorgeschlagene C ++ - Makro zu erstellen, da C ++ bereits "nicht" versteht. Verwandte: stackoverflow.com/questions/2393673/c-and-or-not-xor-keywords
frozenkoi
Das stimmt, aber es ist nur ein Schlüsselwort für den C ++ 0X-Standard. Vorher war es nur ein weiteres Makro.
Fabio Ceconello
0

Die Größe ist wichtig ;)

In gemischten Ausdrücken ist es einfacher zu lesen:

boolean1 = false
boolean2 = true

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

Und speziell für Ruby ein Beispiel, bei dem es sich um einen großen Unterschied handelt:

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

nil ist nicht falsch, aber es ist auch nicht wahr.

knut
quelle
0

Basierend auf meiner Erfahrung und den Antworten auf meine Frage, die Sie verlinkt haben.

Einige Leute bevorzugen es, if (Bedingung) zu verwenden, weil es kürzer zu schreiben ist. und für mich macht es tatsächlich Sinn, zum Beispiel (! isValidated ()) Ich las dies als nicht validiert. Aber für mich basiert alles auf persönlichen Vorlieben und es hängt von der logischen Struktur der isValidated () -Methode ab, ob sie entweder true oder false zurückgibt

KyelJmD
quelle
0

Wenn Sie Ihre Variable richtig benannt haben, !booleanist dies natürlicher. Es spricht not booleanjeden an, der genug Programmierer ist, um Code mental zu lesen .

Leichtigkeit Rennen mit Monica
quelle
0

Für einige Leute ist es umso besser, je eher eine Bedeutung ausgedrückt wird.

Für diejenigen, die ein "wenn! ..." haben, ist das schneller als ein "wenn ...", wenn sie den gesamten Zustand durchlesen müssen (was eigentlich ziemlich lang sein könnte, z. B. (thisThing = thatThing oder etwas = das andere) ODER ( thinga = thingb und thinga = thingd) usw.), nur um am Ende == false zu finden.

Das haben! (Ich bevorzuge eigentlich ein Nicht, wenn die Sprache es zulässt.) Ganz vorne wird das englische 'Nicht' für diese Bedingung eher angezeigt.

Dieses Problem führt auch zu Überlegungen zur Verwendung untilin Sprachen, die es unterstützen, z. Wie andere sagen, ist der Ausdruck natürlicher Sprache das Ziel. Ich mag das obige Beispiel "Sonne scheint".

Junkie
quelle
0

Ein weiterer Grund ist, dass, wenn Sie in einer Codebasis arbeiten, die mehrere Sprachen verwendet, wenn es eine idiomatische Methode gibt, um etwas zu tun, das in allen Sprachen sicher ist, es eine ziemlich gute Idee ist, dies überall so zu tun, damit Sie eine gute Gewohnheit bilden und sind weniger wahrscheinlich zu stolpern.

Ich kann mich nicht von irgendwo , dass if (!variable)(oder Äquivalente, wie if not variableje nach Sprache) nicht sicher ist, während zB if self.is_ready() == False: ...nicht sicher in Python ist , wenn self.is_ready()Rückkehr None, jetzt oder in der Zukunft, die eine völlig vernünftige Sache wäre , es zu tun zeigen an, dass es nicht fertig ist, da Nonees genauso falsch ist wie False.

daphtdazz
quelle