'AND' vs '&&' como operador

298

Tengo una base de código donde los desarrolladores decidieron usar ANDy en ORlugar de &&y ||.

Sé que hay una diferencia en la precedencia de los operadores ( &&va antes and), pero con el marco dado ( PrestaShop para ser precisos) claramente no es una razón.

¿Qué versión está utilizando? ¿Es andmás legible que &&? ¿O no hay diferencia?

ts.
fuente
1
Tenga en cuenta que ~es el operador NOT en cuanto a bits y no el lógico. ;-)
Gumbo
2
Sí, lo sé. Malos hábitos :) . Es un poco extraño que en PHP haya 'y', 'o' y 'xor', pero no hay 'no', ¿no?
ts.
1
@ts: la respuesta correcta aquí es la proporcionada por R. Bemrose stackoverflow.com/questions/2803321/and-vs-as-operator/…
Marco Demaio
44
! es el operador lógico no
Razor Storm
2
@chiliNUT muy bien. En ese momento debe haber tenido sentido. Parece que la respuesta incorrecta acechando ha sido castigada en este punto :)
doublejosh

Respuestas:

664

Si usas ANDy OR, eventualmente te tropezarás con algo como esto:

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

¿Quieres adivinar lo que $truthinesses igual?

Si dijiste false... bzzzt, lo siento, ¡mal!

$truthinessarriba tiene el valor true. ¿Por qué? =tiene mayor precedencia que and. La adición de paréntesis para mostrar el orden implícito aclara esto:

($truthiness = $this_one) and $that

Si usó en &&lugar del andprimer ejemplo de código, funcionaría como se esperaba y sería false.

Como se discute en los comentarios a continuación, esto también funciona para obtener el valor correcto, ya que los paréntesis tienen mayor prioridad que =:

$truthiness = ($this_one and $that)
Powerlord
fuente
135
+1: esto debería hacerse alto y claro en la documentación de PHP, o PHP debería cambiar y dar la misma prioridad a estos operadores o DEPRECATE de and oruna vez por todas. Vi demasiadas personas pensando que son exactamente lo mismo y las respuestas aquí son más testimonios.
Marco Demaio
11
En realidad, otros lenguajes (por ejemplo, Perl y Ruby) también tienen estas variantes con la misma distinción de precedencia, por lo que no sería sensato desviarse de este estándar (por desconcertante que sea para los principiantes) al hacer que la precedencia sea igual en PHP. Sin mencionar la compatibilidad con versiones anteriores de toneladas de aplicaciones PHP.
Mladen Jablanović
23
La incapacidad de las personas para leer la documentación de un idioma no hace que las decisiones del idioma sean incorrectas. Como señala Mladen, Perl y Ruby también usan estos operadores adicionales, y con las mismas precedencia. Permite construcciones como $foo and bar(), que son atajos agradables para sentencias if. Si el comportamiento inesperado (por mala documentación, o no leerlo) fuera una razón para no usar algo de lo que no estaríamos hablando en absoluto usando PHP.
Altreus
2
Pasé 3 minutos para encontrar la línea incorrecta: $ this = true , :( y qué hay de $ truthiness = ($ this y $ that); se ve mejor para mí :)
Dmitriy Kozmenko
66
Estoy de acuerdo con Dmitriy: envolver la evaluación booleana entre paréntesis ayuda a aclarar la intención del código. Creo que el operador y su función tal como existen ahora son valiosos y consistentes con otros lenguajes, es tarea del programador entender el lenguaje.
Jon z
43

Dependiendo de cómo se use, puede ser necesario e incluso útil. 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;

Pero en la mayoría de los casos parece más un gusto de desarrollador, como cada vez que ocurre esto que he visto en el marco de CodeIgniter como @Sarfraz ha mencionado.

adamJLev
fuente
2
Vale la pena señalar que el "verdadero" no se ignora si esa expresión es parte de una declaración más grande. Considere el caso if ($f = false or true) $f = true;: el resultado sería que $fse convierte en verdadero al final, porque la expresión se evalúa como verdadera en general.
Chris Browne
1
no, simplemente sobrescribió la variable más tarde. la expresión aún se evalúa como falsa, luego la sobrescribió con verdadero en la siguiente línea.
r3wt
2
En realidad, tenía razón. Primero, $fse le asigna falso, pero la condición se evalúa como verdadera, por lo que $fse sobrescribe. Si la condición se evalúa como falsa, $fnunca se sobrescribirá de ninguna manera.
ahouse101
Es ridículo sugerir que los desarrolladores deben seguir su propio gusto. Olvidar la pesadilla de otro desarrollador que intenta mantener el mismo código, el desarrollador que escribió el código en sí sería cometer errores semánticos en cualquier código escrito porque s / él prefieren andmás &&, donde andfunciona como se espera en sólo algunas situaciones y &&funciona como se espera en toda situaciones
ADTC
13

Por seguridad, siempre hago paréntesis entre mis comparaciones y las espacio. De esa manera, no tengo que depender de la precedencia del operador:

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )
Capitán Kenpachi
fuente
29
Personalmente, creo que agregar paréntesis innecesarios adicionales hace que leer sea más confuso que tener justo lo que necesita. Por ejemplo, creo que esto es mucho más fácil de leer: if (($ i == 0 && $ b == 2) || ($ c == 3 && $ f! = 5))
rooby
44
Creo que este es el código más bonito que he visto en todo el día. Buen trabajo.
rm-vanda
Como PHP es un lenguaje interpretado, se ejecutará rápidamente si no utiliza espacios en blanco innecesarios o nuevas líneas en su código. Si hace lo mismo en un lenguaje compilado, solo llevará más tiempo compilarlo, pero no tendrá efecto en el tiempo de ejecución. No quiero decir que hacerlo una vez marque la diferencia, pero en una aplicación completa que usa php + javascript, ambos escribieron como en el ejemplo ... los tiempos de carga serán mayores con seguridad. Explicación: Los espacios en blanco y las nuevas líneas se ignoran, pero para ignorarlos, deben verificarse. Esto sucede en tiempo de ejecución en langs interpretados y al compilar en unos compilados.
JoelBonetR
@JoelBonetR si está utilizando php opcache o similar, su preocupación por los tiempos de carga es irrelevante. Espero que nadie esté ejecutando un sitio php de producción sin él ...
PeloNZ
@PeloNZ para que puedas escribir sucio porque de todos modos se almacenará en caché y todo el proyecto tardará solo un segundo más en cargarse cuando se actualice, ¿eh? Para limpiar el código es para usted y sus compañeros de equipo, preocuparse por los tiempos era solo un punto que la mayoría de las personas ignora o simplemente no sabía.
JoelBonetR
11

La precedencia difiere entre && y y (&& tiene mayor precedencia que y), algo que causa confusión cuando se combina con un operador ternario. Por ejemplo,

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

devolverá una cadena mientras que

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

devolverá un booleano .

Arviman
fuente
10

Dado que andtiene una precedencia inferior a la =que puede usar en la asignación de condiciones:

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
fuente
2

Permítanme explicar la diferencia entre “y” - “&&” - "&".

"&&" y "y" ambos son operaciones lógicas AND y hacen lo mismo, pero la precedencia del operador es diferente.

La precedencia (prioridad) de un operador especifica cuán "estrechamente" une dos expresiones. Por ejemplo, en la expresión 1 + 5 * 3, la respuesta es 16 y no 18 porque el operador de multiplicación ("*") tiene mayor prioridad que el operador de suma ("+").

Si los mezcla en una sola operación, podría obtener resultados inesperados en algunos casos , siempre recomiendo usar &&, pero esa es su elección.


Por otro lado, "&" es una operación AND a nivel de bits . Se utiliza para la evaluación y manipulación de bits específicos dentro del valor entero.

Ejemplo si lo haces (14 y 7) el resultado sería 6.

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

¿Qué versión está utilizando?

Si los estándares de codificación para la base de código particular para la que escribo el código especifican qué operador debe usarse, definitivamente lo usaré. Si no es así, y el código dicta cuál debe usarse (no es frecuente, se puede solucionar fácilmente), entonces lo usaré. De lo contrario, probablemente && .

¿Es 'y' más legible que '&&'?

¿Es más legible para usted ? ¡La respuesta es sí y no dependiendo de muchos factores, incluido el código que rodea al operador y, de hecho, la persona que lo lee!

|| hay ~ diferencia?

Si. Ver operadores lógicos para ||y operadores bit a bit para ~.

salathe
fuente
0

Supongo que es cuestión de gustos, aunque (por error) mezclarlos podría causar algunos comportamientos no deseados:

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

true and false || false; // returns true

Por lo tanto, usando && y || es más seguro porque tienen la más alta prioridad. En cuanto a la legibilidad, diría que estos operadores son lo suficientemente universales.

ACTUALIZACIÓN : Sobre los comentarios que dicen que ambas operaciones devuelven falso ... bueno, de hecho el código anterior no devuelve nada, lamento la ambigüedad. Para aclarar: el comportamiento en el segundo caso depende de cómo se use el resultado de la operación. Observe cómo la precedencia de los operadores entra en juego aquí:

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

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

La razón $a === truees porque el operador de asignación tiene prioridad sobre cualquier operador lógico, como ya se explicó muy bien en otras respuestas.

nuqqsa
fuente
16
Esto no es cierto, todos devuelven falso.
Jay
0

Aquí hay un pequeño ejemplo de contador:

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

salida:

bool(false)

Diría que este tipo de error tipográfico es mucho más probable que cause problemas insidiosos (de la misma manera que =vs ==) y es mucho menos probable que se note que adn/ rotypos, que marcará como errores de sintaxis. También encuentro y / o es mucho más fácil de leer. FWIW, la mayoría de los marcos PHP que expresan una preferencia (la mayoría no) especifican y / o. Tampoco me he encontrado con un caso real y no inventado en el que hubiera importado.

Synchro
fuente
0

Otro buen ejemplo usando ifdeclaraciones sin =operaciones de asignación.

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

y

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

porque ANDtiene una precedencia más baja y, por lo tanto, ||una precedencia más alta.

Estos son diferentes en los casos de true, false, falsey true, true, false. Consulte https://ideone.com/lsqovs para obtener un ejemplo detallado.

Conocido
fuente