'AND' vs '&&' come operatore


298

Ho una base di codice in cui gli sviluppatori hanno deciso di utilizzare ANDe ORinvece di &&e ||.

So che c'è una differenza nella precedenza degli operatori ( &&va prima and), ma con il framework dato ( PrestaShop per la precisione) non è chiaramente un motivo.

Che versione stai usando? È andpiù leggibile di &&? O non c'è differenza?


1
Si noti che ~è l'operatore NOT bit-saggio e non logico. ;-)
Gumbo,

2
Si, lo so. Cattive abitudini :) . È un po 'strano che in PHP ci siano' e ',' o 'e' xor ', ma non c'è' non ', no?
ts.

1
@ts: la risposta corretta qui è quello fornito da R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/...
Marco Demaio

4
! è l'operatore logico non
Razor Storm,

2
@chiliNUT abbastanza bene. All'epoca doveva avere un senso. Sembra che la nascosta risposta errata sia stata punita a questo punto :)
doublejosh

Risposte:


664

Se usi ANDe OR, alla fine sarai inciampato in qualcosa del genere:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

Vuoi indovinare ciò che è $truthinessuguale?

Se hai detto false... bzzzt, scusa, sbaglio!

$truthinesssopra ha il valore true. Perché? =ha una precedenza superiore a and. L'aggiunta di parentesi per mostrare l'ordine implicito rende questo più chiaro:

($truthiness = $this_one) and $that

Se hai usato &&invece che andnel primo esempio di codice, funzionerebbe come previsto ed è false.

Come discusso nei commenti seguenti, questo funziona anche per ottenere il valore corretto, poiché le parentesi hanno una precedenza più alta di =:

$truthiness = ($this_one and $that)

135
+1: questo dovrebbe essere reso forte e chiaro nella documentazione di PHP, oppure PHP dovrebbe cambiare e dare la stessa precedenza a questi operatori o DEPRECARE and oruna volta per tutte. Ho visto troppe persone pensare che siano esattamente la stessa cosa e le risposte qui sono più testimonianze.
Marco Demaio,

11
In realtà, anche altre lingue (ad esempio, Perl e Ruby) hanno queste varianti con la stessa distinzione di precedenza, quindi non sarebbe sensato deviare da questo standard (per quanto sconcertante possa essere per i principianti) rendendo la precedenza uguale in PHP. Per non parlare della retrocompatibilità di tonnellate di applicazioni PHP.
Mladen Jablanović il

23
L'incapacità delle persone di leggere la documentazione per una lingua non rende sbagliate le decisioni della lingua. Come osserva Mladen, anche Perl e Ruby usano questi operatori extra e con le stesse precedenti. Permette costrutti come $foo and bar(), che sono delle belle scorciatoie per le istruzioni if. Se un comportamento imprevisto (da una cattiva documentazione o dal non leggerlo) fosse una ragione per non usare qualcosa di cui non parleremmo usando PHP.
Altreus il

2
Ho impiegato 3 minuti per trovare la linea sbagliata: $ this = true , :( e che dire di $ truthiness = ($ this e $ that); è meglio per me :)
Dmitriy Kozmenko

6
Concordo con Dmitriy: racchiudere la valutazione booleana tra parentesi aiuta a chiarire l'intento del codice. Penso che l'operatore e la sua funzione come esistano ora siano preziosi e coerenti con altre lingue, è compito del programmatore comprendere la lingua.
Jon z,

43

A seconda di come viene utilizzato, potrebbe essere necessario e persino utile. 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;

Ma nella maggior parte dei casi sembra più una cosa di gusto per gli sviluppatori, come ogni evenienza di questo che ho visto nel framework CodeIgniter come @Sarfraz ha menzionato.


2
Vale la pena notare che il "vero" non viene ignorato se quell'espressione fa parte di un'istruzione più ampia. Considera il caso if ($f = false or true) $f = true;: il risultato sarebbe che $falla fine diventerà vero, poiché l'espressione viene valutata come vera complessiva.
Chris Browne,

1
no, hai semplicemente sovrascritto la variabile in seguito. l'espressione viene comunque valutata come falsa, quindi la sovrascrivi con true nella riga successiva.
rw

2
In realtà, aveva ragione. Innanzitutto, $fviene assegnato falso, ma la condizione viene valutata vera, quindi $fviene sovrascritta. Se la condizione fosse valutata come falsa, $fnon sarebbe mai stata sovrascritta in entrambi i modi.
ahouse101

È ridicolo suggerire agli sviluppatori di seguire i propri gusti. Dimenticate l'incubo di un altro sviluppatore cercando di mantenere lo stesso codice, lo sviluppatore che ha scritto il codice stesso sarebbe fare errori semantici in qualsiasi codice scritto perché s / he preferito andsopra &&, dove andfunziona come previsto solo in alcune situazioni e &&funziona come previsto in tutte le situazioni.
ADTC

13

Per sicurezza, parentizzo sempre i miei confronti e li distacco. In questo modo, non devo fare affidamento sulla precedenza dell'operatore:

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

29
Personalmente penso che l'aggiunta di parentesi non necessarie renda la lettura più confusa che avere proprio ciò di cui hai bisogno. Ad esempio, penso che sia molto più facile da leggere: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
rooby

4
Penso che questo sia il pezzo di codice più carino che abbia guardato tutto il giorno. Buon lavoro.
rm-vanda,

Poiché PHP è un linguaggio interpretato, funzionerà rapidamente se non usi spazi bianchi non necessari o nuove righe sul tuo codice. Se fai lo stesso su un linguaggio compilato, ci vorrà solo più tempo per la compilazione, ma non avrà effetto sul runtime. Non intendo farlo una volta segnerà una differenza, ma su un'intera applicazione usando php + javascript entrambi hanno scritto come nell'esempio ... i tempi di caricamento saranno sicuramente più grandi. Spiegazione: gli spazi bianchi e le nuove linee vengono ignorati, ma per ignorarli devono essere controllati. Ciò accade in fase di esecuzione su lang interpretati e durante la compilazione su quelli compilati.
JoelBonetR,

@JoelBonetR se stai utilizzando php opcache o simili, la tua preoccupazione per i tempi di caricamento è irrilevante. Spero che nessuno stia gestendo un sito php di produzione senza di esso ...
PeloNZ,

@PeloNZ in modo da poter scrivere sporco perché verrà comunque memorizzato nella cache e l'intero progetto impiegherà solo un secondo in più per caricarsi durante l'aggiornamento, eh? La pulizia del codice è per te e per i tuoi compagni di squadra, preoccuparsi dei tempi era solo un punto che la maggior parte delle persone ignora o semplicemente non sapeva.
JoelBonetR,

11

La precedenza differisce tra && e e (&& ha una precedenza più alta di e), qualcosa che provoca confusione quando combinato con un operatore ternario. Per esempio,

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

restituirà una stringa mentre

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

restituirà un valore booleano .


10

Poiché andha una precedenza inferiore a quella =che puoi usare nell'assegnazione delle condizioni:

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

Lasciami spiegare la differenza tra “e” - “&&” - "&".

"&&" e "e" sono entrambi operazioni logiche AND e fanno la stessa cosa, ma la precedenza dell'operatore è diversa.

La precedenza (priorità) di un operatore specifica quanto "strettamente" lega due espressioni insieme. Ad esempio, nell'espressione 1 + 5 * 3, la risposta è 16 e non 18 perché l'operatore di moltiplicazione ("*") ha una precedenza maggiore rispetto all'operatore di addizione ("+").

Mischiandoli insieme in un'unica operazione, potresti ottenere risultati imprevisti in alcuni casi, ti consiglio di usare sempre &&, ma è una tua scelta.


D'altra parte "&" è un'operazione AND bit a bit . È utilizzato per la valutazione e la manipolazione di bit specifici all'interno del valore intero.

Esempio se lo fai (14 e 7) il risultato sarebbe 6.

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

1

Che versione stai usando?

Se gli standard di codifica per la particolare base di codice per cui sto scrivendo il codice specifica quale operatore debba essere usato, lo userò sicuramente . In caso contrario, e il codice indica quale dovrebbe essere usato (non spesso, può essere facilmente risolto) allora lo userò. Altrimenti, probabilmente && .

"E" sono più leggibili di "&&"?

È più leggibile per te . La risposta è sì e no a seconda di molti fattori tra cui il codice attorno all'operatore e in effetti la persona che lo legge!

|| c'è ~ differenza?

Sì. Vedere operatori logici per ||e operatori bit a bit per ~.


0

Immagino sia una questione di gusti, anche se (erroneamente) mescolarli potrebbe causare comportamenti indesiderati:

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

true and false || false; // returns true

Quindi, usando && e || è più sicuro perché hanno la massima precedenza. Per quanto riguarda la leggibilità, direi che questi operatori sono abbastanza universali.

AGGIORNAMENTO : Circa i commenti che affermano che entrambe le operazioni restituiscono false ... beh, in effetti il ​​codice sopra non restituisce nulla, mi dispiace per l'ambiguità. Per chiarire: il comportamento nel secondo caso dipende da come viene utilizzato il risultato dell'operazione. Osserva come entra in gioco la precedenza degli operatori:

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

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

Il motivo $a === trueè perché l'operatore di assegnazione ha la precedenza su qualsiasi operatore logico, come già spiegato molto bene in altre risposte.


16
Questo non è vero, tutti restituiscono falso.
Jay,

0

Ecco un piccolo esempio contatore:

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

produzione:

bool(false)

Direi che questo tipo di refuso ha molte più probabilità di causare problemi insidiosi (più o meno allo stesso modo di =vs ==) ed è molto meno probabile che si notino adn/ roerrori di battitura che segnaleranno come errori di sintassi. Inoltre trovo e / o è molto più facile da leggere. FWIW, la maggior parte dei framework PHP che esprimono una preferenza (la maggior parte non lo specifica) specifica e / o. Inoltre non mi sono mai imbattuto in un caso reale e non inventato in cui avrebbe avuto importanza.


0

Un altro bell'esempio usando ifistruzioni senza =operazioni di assegnazione.

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

e

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

perché ANDha una precedenza inferiore e quindi|| una precedenza più alta.

Questi sono diversi nei casi di true, false, falsee true, true, false. Vedi https://ideone.com/lsqovs per un esempio elaborato.

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.