„AND” vs „&&” jako operator


298

Mam bazę kodów, w której programiści zdecydowali się użyć ANDi ORzamiast &&i ||.

Wiem, że istnieje różnica w pierwszeństwie operatorów ( &&wcześniej and), ale przy danym frameworku (a dokładniej PrestaShop ) wyraźnie nie jest to powód.

Jakiej wersji używasz? Czy jest andbardziej czytelny niż &&? Czy nie ma różnicy?


1
Zauważ, że ~jest to bitowy operator NOT, a nie logiczny. ;-)
Gumbo

2
Tak, wiem. Złe nawyki :) . To trochę dziwne, że w PHP są „i”, „lub” i „xor”, ale nie ma „nie”, prawda?
ts.

1
@ts: prawidłowa odpowiedź tutaj jest udzielona przez R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/…
Marco Demaio

4
! jest logicznym nie operatorem
Razor Storm

2
@chiliNUT całkiem dobrze. W tym czasie musiało to mieć sens. Wygląda na to, że czyhająca w tym miejscu niepoprawna odpowiedź została w tym momencie ukarana :)
doublejosh

Odpowiedzi:


663

Jeśli użyjesz ANDi OR, w końcu potkniesz się o coś takiego:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

Chcesz zgadnąć, co $truthinessjest równe?

Jeśli powiedziałeś false... bzzzt, przepraszam, źle!

$truthinesspowyżej ma wartość true. Dlaczego? =ma wyższy priorytet niż and. Dodanie nawiasów pokazujących ukrytą kolejność czyni to jaśniejszym:

($truthiness = $this_one) and $that

Jeśli użyłeś &&zamiast andw pierwszym przykładzie kodu, działałoby to zgodnie z oczekiwaniami i będziefalse .

Jak omówiono w komentarzach poniżej, działa to również w celu uzyskania poprawnej wartości, ponieważ nawiasy mają wyższy priorytet niż =:

$truthiness = ($this_one and $that)

135
+1: należy to wyjaśnić w dokumentacji PHP, inaczej PHP powinno się zmienić i dać tym samym pierwszeństwo tym operatorom lub DEPRECATE and orraz na zawsze. Widziałem zbyt wielu ludzi myślących, że są dokładnie tacy sami, a odpowiedzi tutaj to więcej referencji.
Marco Demaio

11
W rzeczywistości inne języki (na przykład Perl i Ruby) również mają te warianty z tym samym rozróżnieniem pierwszeństwa, więc nie byłoby rozsądne odstąpienie od tego standardu (choć może to być zagadką dla początkujących) poprzez wyrównanie pierwszeństwa w PHP. Nie wspominając o wstecznej kompatybilności ton aplikacji PHP.
Mladen Jablanović

23
Brak umiejętności czytania dokumentacji danego języka nie powoduje, że decyzje podejmowane w tym języku są błędne. Jak zauważa Mladen, Perl i Ruby również używają tych dodatkowych operatorów i z tymi samymi priorytetami. Pozwala na takie konstrukcje $foo and bar(), które są ładnymi skrótami do instrukcji if. Jeśli nieoczekiwane zachowanie (z powodu złej dokumentacji lub jej braku czytania) było powodem, aby nie używać czegoś, nie mówilibyśmy w ogóle o korzystaniu z PHP.
Altreus,

2
Spędziłem 3 minuty na znalezieniu niewłaściwej linii: $ this = true , :( a co z $ trueiness = ($ this and $ that); dla mnie wygląda lepiej :)
Dmitriy Kozmenko

6
Zgadzam się z Dmitriyem - zawijanie oceny w nawiasie boolowskim pomaga wyjaśnić cel kodu. Myślę, że operator i jego funkcja, ponieważ teraz istnieją, są cenne i spójne z innymi językami, zadaniem programisty jest zrozumienie języka.
Jon z

43

W zależności od sposobu użytkowania może być konieczne, a nawet przydatne. 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;

Ale w większości przypadków wygląda to bardziej na gust programisty, jak każde wystąpienie tego, co widziałem w frameworku CodeIgniter, jak @Sarfraz.


2
Warto zauważyć, że „prawda” nie jest ignorowana, jeśli to wyrażenie jest częścią większej wypowiedzi. Rozważmy przypadek if ($f = false or true) $f = true;- wynik byłby taki, że $fostatecznie stanie się on prawdą, ponieważ wyrażenie ogólnie ocenia się jako prawdziwe.
Chris Browne

1
nie, po prostu zastąpiłeś zmienną później. wyrażenie nadal ma wartość false, a następnie zastąpiłeś je wartością true w następnym wierszu.
r3wt

2
Właściwie miał rację. Najpierw $fzostaje przypisane fałsz - ale warunek ma wartość true, a następnie $fzostaje zastąpiony. Jeśli warunek zostanie oceniony jako fałszywy, $fnigdy nie zostanie zastąpiony w żaden sposób.
ahouse101

Śmieszne jest sugerowanie, że programiści powinni postępować według własnego gustu. Zapomnij o koszmarze innego programisty próbującego utrzymać ten sam kod, programista, który sam napisał kod, popełnia błędy semantyczne w każdym kodzie, ponieważ napisał kod, ponieważ preferuje andon &&, w którym anddziała zgodnie z oczekiwaniami tylko w niektórych sytuacjach i &&działa zgodnie z oczekiwaniami we wszystkich sytuacje.
ADTC

13

Dla bezpieczeństwa zawsze porównuję nawiasy i porównuję je. W ten sposób nie muszę polegać na pierwszeństwie operatora:

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )

29
Osobiście uważam, że dodanie dodatkowych niepotrzebnych nawiasów sprawia, że ​​czytanie jest bardziej mylące niż posiadanie tylko tego, czego potrzebujesz. Na przykład uważam, że jest to o wiele łatwiejsze do odczytania: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
rooby

4
Myślę, że to najładniejszy fragment kodu, na który patrzyłem przez cały dzień. Dobra robota.
rm-vanda

Ponieważ PHP jest językiem interpretowanym, będzie działał szybko, jeśli nie użyjesz niepotrzebnych białych znaków lub nowych wierszy w kodzie. Jeśli zrobisz to samo w skompilowanym języku, kompilacja zajmie więcej czasu, ale nie wpłynie na środowisko uruchomieniowe. Nie mam na myśli, że zrobienie tego raz zaznaczy różnicę, ale dla całej aplikacji korzystającej z php + javascript napisane jak w przykładzie ... czasy ładowania będą na pewno dłuższe. Objaśnienie: Białe znaki i nowe wiersze są ignorowane, ale aby je zignorować, należy je sprawdzić. Dzieje się tak w czasie wykonywania na interpretowanych językach i podczas kompilacji na skompilowanych językach.
JoelBonetR

@JoelBonetR, jeśli używasz phc opcache lub podobnego, twoje obawy dotyczące czasów ładowania są nieistotne. Mam nadzieję, że nikt nie prowadzi produkcyjnej strony php bez niej ...
PeloNZ

@PeloNZ, więc możesz pisać brudne, ponieważ i tak zostaną one zapisane w pamięci podręcznej, a cały projekt zajmie tylko sekundę załadowania podczas odświeżania, co? Aby kod czysty był dla ciebie i twoich kolegów z drużyny, niepokój o czas był tylko punktem, który większość ludzi ignoruje lub po prostu nie wie.
JoelBonetR

11

Pierwszeństwo różni się pomiędzy && i i (&& ma wyższy priorytet niż i), co powoduje zamieszanie w połączeniu z operatorem trójskładnikowym. Na przykład,

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

zwróci ciąg , natomiast

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

zwróci wartość logiczną .


10

Ponieważ andma niższy priorytet niż =można go użyć w przypisaniu warunków:

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

2

Pozwól, że wyjaśnię różnicę między „a” - „&&” - „&”.

„&&” oraz „i” są logicznymi operacjami AND i robią to samo, ale priorytet operatorów jest inny.

Priorytet (priorytet) operatora określa, jak „ściśle” wiąże dwa wyrażenia razem. Na przykład w wyrażeniu 1 + 5 * 3 odpowiedź to 16, a nie 18, ponieważ operator mnożenia („*”) ma wyższy priorytet niż operator dodawania („+”).

Mieszanie ich razem w jednej operacji może dać nieoczekiwane rezultaty. W niektórych przypadkach zalecam zawsze używanie &&, ale to twój wybór.


Z drugiej strony „&” jest operacją bitową AND . Służy do oceny i manipulowania konkretnymi bitami w ramach wartości całkowitej.

Przykład, jeśli to zrobisz (14 i 7), wynikiem będzie 6.

7   = 0111
14  = 1110
------------
    = 0110 == 6

1

Jakiej wersji używasz?

Jeśli standardy kodowania dla konkretnej bazy kodu, w której piszę kod, określają, którego operatora należy użyć, na pewno go użyję. Jeśli nie, a kod określa, które należy użyć (nie często można łatwo obejść), użyję tego. W przeciwnym razie prawdopodobnie && .

Czy „i” są bardziej czytelne niż „&&”?

Czy to dla ciebie bardziej czytelne . Odpowiedź brzmi „ tak” i „nie” w zależności od wielu czynników, w tym kodu wokół operatora i osoby, która go czyta!

|| jest ~ różnica?

Tak. Zobacz operatorów logicznych dla ||i operatory bitowe dla ~.


0

Myślę, że to kwestia gustu, chociaż (błędnie) pomieszanie ich może spowodować pewne niepożądane zachowania:

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

true and false || false; // returns true

Stąd użycie && i || jest bezpieczniejszy, ponieważ mają najwyższy priorytet. Jeśli chodzi o czytelność, powiedziałbym, że operatorzy ci są wystarczająco uniwersalni.

AKTUALIZACJA : O komentarzach mówiących, że obie operacje zwracają fałsz ... cóż, w rzeczywistości powyższy kod nic nie zwraca, przepraszam za dwuznaczność. Aby wyjaśnić: zachowanie w drugim przypadku zależy od sposobu wykorzystania wyniku operacji. Zwróć uwagę, w jaki sposób odgrywa tutaj pierwszeństwo operatorów:

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

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

Powodem $a === truejest to, że operator przypisania ma pierwszeństwo przed dowolnym operatorem logicznym, jak już bardzo dobrze wyjaśniono w innych odpowiedziach.


16
To nie jest prawda, wszystkie zwracają fałsz.
Jay

0

Oto mały licznik:

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

wynik:

bool(false)

Powiedziałbym, że tego rodzaju literówka jest znacznie bardziej narażona na podstępne problemy (w podobny sposób jak =vs ==) i jest znacznie mniej zauważalna niż adn/ roliterówki, które będą oznaczać błędy składniowe. Znajduję też i / lub jest znacznie łatwiejszy do odczytania. FWIW, większość frameworków PHP, które wyrażają preferencje (większość nie) określa i / lub. Nigdy też nie spotkałem prawdziwej, nieskomplikowanej sprawy, w której miałoby to znaczenie.


0

Kolejny fajny przykład użycia ifinstrukcji bez =operacji przypisania.

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

i

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

ponieważ ANDma niższy priorytet, a tym samym ||wyższy priorytet.

Różnią się one w przypadkach true, false, falsei true, true, false. Zobacz https://ideone.com/lsqovs w celu uzyskania szczegółowego przykładu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.