Últimamente, he estado trabajando mucho en PHP y específicamente en el marco de WordPress. Noto mucho código en forma de:
if ( 1 == $options['postlink'] )
Donde hubiera esperado ver:
if ( $options['postlink'] == 1 )
¿Es esta una convención que se encuentra en ciertos lenguajes / marcos? ¿Hay alguna razón por la cual el enfoque anterior es preferible al segundo (desde una perspectiva de procesamiento, una perspectiva de análisis o incluso una perspectiva humana)?
¿O es simplemente una cuestión de gustos? Siempre he pensado mejor al realizar una prueba, que el elemento variable que se está probando contra alguna constante está a la izquierda. Parece encajar mejor con la forma en que haríamos la pregunta en lenguaje natural: "si el pastel es chocolate" en lugar de "si el chocolate es el pastel".
Respuestas:
La razón principal para hacer esto (lo que se llama "Yoda condicional") es para evitar accidentes mediante los cuales accidentalmente usa un operador de asignación (
=
) en lugar del operador de comparación igual (==
).Es decir, si cometió el error de hacer:
La declaración evaluará
true
(o, en el caso de algunos lenguajes, como PHP, un valor verdadero) y tendrá un error difícil de encontrar.Pero si lo hiciste:
Recibirá un error fatal porque no puede asignar
$foo
a un número entero.Pero como usted señaló, invertir el orden generalmente hace que las cosas sean menos legibles. Por lo tanto, muchos estándares de codificación (pero no todos, incluido WordPress ) sugieren o requieren a
$foo == 1
pesar de los beneficios de la búsqueda de errores1 == $foo
.En general, mi consejo es seguir cualquier estándar de codificación establecido que exista, si hay uno: para WordPress, eso significa usar los condicionales de Yoda.
Cuando no lo hay, y es imposible establecer uno a través del consenso con sus pares, es decisión del distribuidor.
fuente
:=
ser el operador de asignación (con==
prueba de igualdad) para evitar este tipo de problemas.=
lugar de==
. La diferencia está tan acentuada en todas partes que nunca los confundí. Por otro lado, he leído muchos códigos que son confusos o difíciles de entender. Como tal, pondría las prioridades en la legibilidad :). De todos modos, buena respuesta.-Wall -Werror
o el equivalente de su compilador / intérprete. Hay muy pocas situaciones en las que una asignación dentro de una condición sea correcta, y mucho menos más legible. Muchos idiomas ni siquiera lo permiten.if($foo = 1)
evalúatrue
en algunos idiomas, en PHP se evalúa a 1 en su lugar;if($foo = 20)
evalúa a 20;if($foo = 0)
evalúa a 0, que a diferencia de los demás es falso. Esto puede agregar una 'capa de complejidad completa al error.Es un mecanismo de codificación defensivo destinado a evitar un uso accidental del operador de asignación.
Considere un mal uso / error del operador de asignación en lugar del operador de igualdad
El condicional anterior siempre devolvería verdadero, pero eso probablemente no sea lo que el programador original tenía en mente. Considere, en su lugar, esto
Aquí, PHP (y la mayoría de los otros lenguajes) se negarían a ejecutarse, ya que es imposible asignar algo al valor fijo de
1
. Al codificar todas las declaraciones condicionales de esta manera, se asegura automáticamente de que no se use accidentalmente un operador de asignación en un condicional.fuente
Me gusta usar esa convención en Java para eliminar la posibilidad de una excepción de puntero nulo. Entonces, algo como esto no le causará ningún problema ni necesitará ningún código adicional:
fuente
En la práctica, muchos compiladores le darán una advertencia si escribe "if (x = 1)" en lugar de "if (x == 1)" porque es muy probable que sea un error.
Con Clang, puede evitar la advertencia diciéndole efectivamente al compilador "Lo digo en serio y sé lo que estoy haciendo", y esto se hace escribiendo "if ((x = 1))". Tenga en cuenta los paréntesis adicionales. Eso también funciona en otras situaciones. declaración if (falsa); puede advertirle que la declaración nunca se ejecuta; declaración if ((falso)); No da esa advertencia.
fuente
if ($array = getSomething()){ // ..so something with $array }