'AND' vs '&&' als Operator

298

Ich habe eine Codebasis, in der Entwickler entschieden haben, ANDund ORanstelle von &&und zu verwenden ||.

Ich weiß, dass es einen Unterschied in der Priorität der Operatoren gibt ( &&geht vorher and), aber mit dem gegebenen Framework ( genauer gesagt PrestaShop ) ist dies eindeutig kein Grund.

Welche Version verwenden Sie? Ist andbesser lesbar als &&? Oder gibt es keinen Unterschied?

ts.
quelle
1
Beachten Sie, dass dies ~der bitweise NICHT-Operator und nicht der logische ist. ;-)
Gumbo
2
Ja, ich weiß. Schlechte Angewohnheiten :) . Es ist ein bisschen seltsam, dass es in PHP 'und', 'oder' und 'xor' gibt, aber es gibt kein 'nicht', nicht wahr?
ts.
1
@ts: Die richtige Antwort hier ist die von R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/…
Marco Demaio
4
! ist der logische Nicht-Operator
Razor Storm
2
@chiliNUT ganz richtig. Zu der Zeit muss es Sinn gemacht haben. Sieht aus wie die lauernde falsche Antwort zu diesem Zeitpunkt bestraft wurde :)
DoubleJosh

Antworten:

664

Wenn Sie ANDund verwenden OR, werden Sie irgendwann von so etwas gestolpert:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

Möchten Sie erraten, was $truthinessgleich ist?

Wenn du gesagt hast false... bzzzt, sorry, falsch!

$truthinessoben hat den Wert true. Warum? =hat eine höhere Priorität als and. Das Hinzufügen von Klammern zur Darstellung der impliziten Reihenfolge macht dies klarer:

($truthiness = $this_one) and $that

Wenn Sie &&anstelle des andersten Codebeispiels verwenden, würde es wie erwartet funktionieren und sein false.

Wie in den Kommentaren unten erläutert, funktioniert dies auch, um den richtigen Wert zu erhalten, da Klammern eine höhere Priorität haben als =:

$truthiness = ($this_one and $that)
Powerlord
quelle
135
+1: Dies sollte in der PHP-Dokumentation laut und deutlich gemacht werden, oder PHP sollte sich ändern und diesen Operatoren den gleichen Vorrang einräumen oder and orein für allemal DEPRECATE . Ich habe zu viele Leute gesehen, die dachten, sie seien genau dasselbe, und die Antworten hier sind mehr Zeugnisse.
Marco Demaio
11
Tatsächlich haben auch andere Sprachen (z. B. Perl und Ruby) diese Varianten mit derselben Prioritätsunterscheidung, sodass es nicht sinnvoll wäre, von diesem Standard abzuweichen (wie verwirrend er auch für Anfänger sein mag), indem die Priorität in PHP gleichgesetzt wird. Ganz zu schweigen von der Abwärtskompatibilität von Tonnen von PHP-Anwendungen.
Mladen Jablanović
23
Die Unfähigkeit der Menschen, die Dokumentation für eine Sprache zu lesen, führt nicht dazu, dass die Entscheidungen der Sprache falsch sind. Wie Mladen bemerkt, verwenden Perl und Ruby auch diese zusätzlichen Operatoren mit denselben Prioritäten. Es erlaubt Konstrukte wie $foo and bar(), die nette Abkürzungen für if-Anweisungen sind. Wenn unerwartetes Verhalten (aufgrund schlechter Dokumentation oder Nichtlesen) ein Grund wäre, etwas nicht zu verwenden, würden wir überhaupt nicht über die Verwendung von PHP sprechen.
Altreus
2
Ich habe 3 Minuten damit verbracht, eine falsche Zeile zu finden: $ this = true , :( und was ist mit $ trueiness = ($ this und $ that); es sieht für mich besser aus :)
Dmitriy Kozmenko
6
Ich stimme Dmitriy zu - das Umschließen der booleschen Auswertung in Klammern hilft, die Absicht des Codes zu verdeutlichen. Ich denke, der Operator und seine Funktion, wie sie jetzt existieren, sind wertvoll und stimmen mit anderen Sprachen überein. Es ist die Aufgabe des Programmierers, die Sprache zu verstehen.
Jon z
43

Je nachdem, wie es verwendet wird, kann es notwendig und sogar praktisch sein. http://php.net/manual/en/language.operators.logical.php

// "||" has a greater precedence than "or"

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;

Aber in den meisten Fällen scheint es eher ein Entwicklergeschmack zu sein, wie jedes Vorkommen, das ich im CodeIgniter-Framework gesehen habe, wie es @Sarfraz erwähnt hat.

adamJLev
quelle
2
Es ist erwähnenswert, dass das "Wahre" nicht ignoriert wird, wenn dieser Ausdruck Teil einer größeren Aussage ist. Betrachten Sie den Fall if ($f = false or true) $f = true;- das Ergebnis wäre, dass $fes am Ende wahr wird, weil der Ausdruck insgesamt als wahr ausgewertet wird.
Chris Browne
1
Nein, Sie haben die Variable später einfach überschrieben. Wenn der Ausdruck immer noch als falsch ausgewertet wird, haben Sie ihn in der nächsten Zeile mit true überschrieben.
r3wt
2
Eigentlich hatte er recht. Zuerst $fwird false zugewiesen - aber die Bedingung wird als true ausgewertet und dann $füberschrieben. Wenn die Bedingung als falsch bewertet $fwürde , würde sie niemals so oder so überschrieben werden.
ahouse101
Es ist lächerlich zu behaupten, die Entwickler sollten ihrem eigenen Geschmack folgen. Vergessen Sie den Albtraum eines anderen Entwicklers, der versucht, denselben Code beizubehalten. Der Entwickler, der den Code selbst geschrieben hat, würde semantische Fehler in jedem Code machen, der geschrieben wurde, weil er / sie es vorgezogen andhat &&, wo er andin nur einigen Situationen &&wie erwartet funktioniert und in allen wie erwartet funktioniert Situationen.
ADTC
13

Aus Sicherheitsgründen setze ich meine Vergleiche immer in Klammern und platziere sie. Auf diese Weise muss ich mich nicht auf die Priorität des Operators verlassen:

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )
Kapitän Kenpachi
quelle
29
Persönlich denke ich, dass das Hinzufügen zusätzlicher unnötiger Klammern das Lesen verwirrender macht, als nur das zu haben, was Sie brauchen. Zum Beispiel denke ich, dass dies viel einfacher zu lesen ist: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
Rooby
4
Ich denke, dies ist der schönste Code, den ich mir den ganzen Tag angesehen habe. Gut gemacht.
RM-Vanda
Da PHP eine interpretierte Sprache ist, wird es schnell ausgeführt, wenn Sie keine unnötigen Leerzeichen oder neuen Zeilen in Ihrem Code verwenden. Wenn Sie dasselbe für eine kompilierte Sprache tun, dauert das Kompilieren nur länger, wirkt sich jedoch nicht auf die Laufzeit aus. Ich meine nicht, dass es einmal einen Unterschied macht, aber bei einer gesamten Anwendung mit PHP + Javascript haben beide wie im Beispiel geschrieben ... Die Ladezeiten werden mit Sicherheit länger sein. Erläuterung: Leerzeichen und neue Zeilen werden ignoriert. Um sie jedoch zu ignorieren, müssen sie überprüft werden. Dies geschieht zur Laufzeit auf interpretierten langs und beim Kompilieren auf kompilierten langs.
JoelBonetR
@JoelBonetR Wenn Sie PHP-Opcache oder ähnliches verwenden, ist Ihre Sorge um die Ladezeiten irrelevant. Ich würde hoffen, dass niemand eine PHP-Produktionsseite ohne diese
betreibt
@PeloNZ, damit du schmutzig schreiben kannst, weil es sowieso zwischengespeichert wird und das gesamte Projekt nur noch eine Sekunde braucht, um beim Aktualisieren geladen zu werden, oder? Das Bereinigen von Code ist für Sie und Ihre Teamkollegen eine Frage des Timings. Dies war nur ein Punkt, den die meisten Leute ignorierten oder einfach nicht wussten.
JoelBonetR
11

Die Priorität unterscheidet sich zwischen && und und (&& hat eine höhere Priorität als und), was in Kombination mit einem ternären Operator Verwirrung stiftet. Zum Beispiel,

$predA && $predB ? "foo" : "bar"

gibt eine Zeichenfolge zurück, während

$predA and $predB ? "foo" : "bar"

gibt einen Booleschen Wert zurück .

Arviman
quelle
10

Da andhat eine niedrigere Priorität, als =Sie es in der Bedingungszuweisung verwenden können:

if ($var = true && false) // Compare true with false and assign to $var
if ($var = true and false) // Assign true to $var and compare $var to false
Justinas
quelle
2

Lassen Sie mich den Unterschied zwischen "und" - "&&" - "&" erklären.

"&&" und "und" sind beide logische UND-Operationen und machen dasselbe, aber die Operator-Priorität ist unterschiedlich.

Die Priorität (Priorität) eines Operators gibt an, wie "eng" zwei Ausdrücke miteinander verbunden werden. Beispielsweise lautet die Antwort im Ausdruck 1 + 5 * 3 16 und nicht 18, da der Multiplikationsoperator ("*") eine höhere Priorität hat als der Additionsoperator ("+").

Das Mischen in einem Arbeitsgang kann in einigen Fällen zu unerwarteten Ergebnissen führen. Ich empfehle, immer && zu verwenden, aber Sie haben die Wahl.


Andererseits ist "&" eine bitweise UND-Verknüpfung . Es wird zur Auswertung und Bearbeitung bestimmter Bits innerhalb des Integer-Werts verwendet.

Beispiel, wenn Sie dies tun (14 & 7), wäre das Ergebnis 6.

7   = 0111
14  = 1110
------------
    = 0110 == 6
Mahmoud Zalt
quelle
1

Welche Version verwendest du?

Wenn die Codierungsstandards für die bestimmte Codebasis, für die ich Code schreibe, angeben, welcher Operator verwendet werden soll, werde ich das definitiv verwenden. Wenn nicht, und der Code schreibt vor, welche verwendet werden sollen (nicht oft, kann leicht umgangen werden), dann werde ich das verwenden. Ansonsten wahrscheinlich && .

Ist 'und' besser lesbar als '&&'?

Ist es besser lesbar zu Ihnen . Die Antwort lautet Ja und Nein, abhängig von vielen Faktoren, einschließlich des Codes um den Bediener und der Person, die ihn liest!

|| Gibt es einen Unterschied?

Ja. Siehe logische Operatoren für ||und bitweise Operatoren für ~.

salathe
quelle
0

Ich denke, es ist Geschmackssache, obwohl das (irrtümliche) Verwechseln zu unerwünschten Verhaltensweisen führen kann:

true && false || false; // returns false

true and false || false; // returns true

Verwenden Sie daher && und || ist sicherer, denn sie haben die höchste Priorität. In Bezug auf die Lesbarkeit würde ich sagen, dass diese Operatoren universell genug sind.

UPDATE : Über die Kommentare, die besagen, dass beide Operationen false zurückgeben ... nun, tatsächlich gibt der obige Code nichts zurück, ich entschuldige mich für die Mehrdeutigkeit. Zur Verdeutlichung: Das Verhalten im zweiten Fall hängt davon ab, wie das Ergebnis der Operation verwendet wird. Beobachten Sie, wie der Vorrang von Operatoren hier ins Spiel kommt:

var_dump(true and false || false); // bool(false)

$a = true and false || false; var_dump($a); // bool(true)

Der Grund dafür $a === trueist, dass der Zuweisungsoperator Vorrang vor jedem logischen Operator hat, wie bereits in anderen Antworten sehr gut erläutert.

nuqqsa
quelle
16
Dies ist nicht wahr, sie alle geben falsch zurück.
Jay
0

Hier ist ein kleines Gegenbeispiel:

$a = true;
$b = true;
$c = $a & $b;
var_dump(true === $c);

Ausgabe:

bool(false)

Ich würde sagen, dass diese Art von Tippfehler weitaus eher heimtückische Probleme verursacht (ähnlich wie =vs ==) und weitaus seltener bemerkt wird als adn/ roTippfehler, die als Syntaxfehler gekennzeichnet werden. Ich finde und / oder ist auch viel einfacher zu lesen. FWIW, die meisten PHP-Frameworks, die eine Präferenz ausdrücken (die meisten nicht), spezifizieren und / oder. Ich bin auch nie auf einen echten, nicht erfundenen Fall gestoßen, in dem es darauf angekommen wäre.

Synchro
quelle
0

Ein weiteres schönes Beispiel für die Verwendung von ifAnweisungen ohne =Zuweisungsoperationen.

if (true || true && false); // is the same as:
if (true || (true && false)); // TRUE

und

if (true || true AND false); // is the same as:
if ((true || true) && false); // FALSE

weil ANDhat eine niedrigere Priorität und damit ||eine höhere Priorität.

Diese unterscheiden sich in den Fällen von true, false, falseund true, true, false. Ein ausführliches Beispiel finden Sie unter https://ideone.com/lsqovs .

Ken
quelle