¿Por qué usar! boolean_variable Over boolean_variable == false

55

Un comentario sobre esta pregunta: comprobando si un método devuelve falso: ¿asignar resultado a una variable temporal, o poner la invocación del método directamente en condicional? dice que debe usar !boolean en lugar de boolean == false cuando esté probando las condiciones. ¿Por qué? Para mí boolean == false es mucho más natural en inglés y es más explícito. Pido disculpas si esto es solo una cuestión de estilo, pero me preguntaba si había alguna otra razón para esta preferencia de !boolean ?

    
pregunta ell 12.04.2017 - 09:31

16 respuestas

148

Cuando veo una línea como if (!lateForMeeting()) , leo esto como "Si no llega tarde" , lo cual es bastante sencillo de entender, a diferencia de if (lateForMeeting() == false) , que D lea como "Si el hecho de llegar tarde a la reunión es falso" .

Tienen un significado idéntico, pero el primero está más cerca de cómo se construiría la oración equivalente en inglés.

    
respondido por el kba 26.02.2012 - 06:13
96

La escritura de == false y == true es redundante. Puede ser llevado a extremos arbitrarios, también. Si empiezas a escribir

if (condition == false) { ... }

Entonces, ¿por qué no

if ((condition == false) == true) { ... }

O por qué no

if ((someExp == anotherExp) == true) { ... }

La moraleja de esta historia es que si condition es una expresión booleana, entonces no es necesario agregar == false ; para eso está el operador ! ;)

    
respondido por el Andres F. 25.02.2012 - 22:37
70

En C y en algunos idiomas similares, la comparación de expresiones booleanas para la igualdad con false o true es un hábito peligroso.

En C, cualquier expresión escalar (numérica o puntero) se puede usar en un contexto booleano, por ejemplo, como la condición de una declaración if . La regla de C es que if (cond) es equivalente a if (cond != 0) ; es decir, cero es falso, y cualquier el valor distinto de cero es verdadero. Si cond es de tipo puntero, 0 se trata como una constante de puntero nula; if (ptr) significa if (ptr != NULL) .

Esto significa que

if (cond)

y

if (cond == true)

no significa lo mismo . El primero es verdadero si cond no es cero; el segundo es verdadero solo si es igual a true , que en C (si tienes #include <stdbool.h> ) es simplemente 1 .

Por ejemplo, la función isdigit() declarada en <ctype.h> devuelve un valor int , 0 si el argumento es un dígito, no es cero si no lo es. Puede devolver 42 para indicar que la condición es verdadera. La comparación de 42 == true fallará.

Sucede que 0 es el único valor que se considera falso, por lo que la comparación de la igualdad con false funcionará; if (!cond) y if (cond == false) hacen lo mismo. Pero si vas a aprovechar eso, debes recordar que compararlo con false está bien, y compararlo con true no. Peor aún, comparando con true funcionará la mayor parte del tiempo (por ejemplo, la igualdad y los operadores relacionales siempre producen 0 o 1 ). Esto significa que cualquier error que introduzcas al usar esto podría ser difícil de rastrear. (No se preocupe, aparecerán en cuanto muestre el código a un cliente importante).

C ++ tiene reglas ligeramente diferentes; por ejemplo, su tipo bool está un poco más integrado en el idioma, y if (cond) convierte cond al tipo bool . Pero el efecto es (en su mayoría) el mismo.

Algunos otros idiomas tienen lo que podríamos llamar booleanos con mejor comportamiento, de modo que cond == true y cond == false (o cualquiera que sea la sintaxis) es seguro. Aun así, todos los idiomas que he visto tienen un operador not o ! ; está ahí, así que también podrías usarlo. Usar cond == false en lugar de !cond o not cond no, en mi opinión, mejora la legibilidad. (Es cierto que el carácter ! puede ser difícil de ver de un vistazo; a veces agrego un espacio después de ! para evitar esto).

Y a menudo puede evitar el problema y mejorar la claridad reorganizando el código ligeramente. Por ejemplo, en lugar de:

if (!cond) {
    do_this();
}
else {
    do_that();
}

puedes escribir:

if (cond) {
     do_that();
}
else {
    do_this();
}

Eso no siempre es mejor, pero no hace daño buscar oportunidades donde están.

Resumen: En C y C ++, las comparaciones de igualdad con true y false son peligrosas, demasiado verbosas y de estilo deficiente. En muchos otros idiomas, estas comparaciones pueden no ser peligrosas, pero aún son demasiado verbosas y tienen un estilo pobre.

    
respondido por el Keith Thompson 26.02.2012 - 00:32
13

Si condition == false es de hecho "mucho más natural en inglés" para usted, debo asumir que no es un hablante nativo. De lo contrario no puedo explicar esto, porque nadie habla así:

  

Si el sol brilla es falso, me quedo en casa.

Compara eso con

  

Si el sol no brilla, me quedo en casa.

Dicho esto, estoy de acuerdo en que el carácter simple, slender ! se pasa por alto fácilmente en el código. Por esa razón, prefiero la palabra clave not cuando es compatible con el idioma. C ++, por ejemplo, permite esto, aunque muchos programadores no lo saben.

Para los idiomas que requieren ! , coloco un espacio entre el operador y el operando. Esto hace que la negación sea mucho más difícil de pasar por alto:

if (! condition) { … }

Observe que todo programador debe traducir este automáticamente , sin pensarlo dos veces, a "no condicionar" en su cabeza. La adquisición de este tipo de fluidez en la lectura de los modismos de los códigos es uno de los primeros pasos para convertirse en un buen programador.

    
respondido por el Konrad Rudolph 27.02.2012 - 02:07
13

Los dos son funcionalmente idénticos, por lo que usar es una cuestión de gustos.

La razón principal por la que I usa == false es que he encontrado que ! es demasiado fácil de pasar por alto cuando se mira el código.

Habiendo sido severamente mordido por esto, he hecho el hábito de dejarlo muy claro al probar falso.

Si el operador hubiera sido nombrado not como en Pascal, no creo que esto se haya convertido en un problema.

    
respondido por el 3 revsuser1249 06.03.2012 - 16:19
7

Cuando veo var == false siempre me pregunto si var es booleano o de un tipo lógico con más de dos valores (con, por ejemplo, un maybe y un undefined , así como true y false , o algo como los nueve valores de IEEE 1164 ).

    
respondido por el AProgrammer 21.11.2012 - 17:54
6

porque a veces puedes escribir boolean = false (con los errores obvios) y false == boolean no parece natural (no importa cuán buena sea la práctica)

    
respondido por el ratchet freak 25.02.2012 - 21:51
4

if (!boolean_variable) se traduce en if the condition is not true .

if (boolean == false) se traduce en if the condition not false is true . Debido a que es una lógica inversa, es más difícil de entender.

    
respondido por el BЈовић 26.02.2012 - 12:56
2

En compiladores (mucho) más antiguos, creo que se dividirían (boolean == false) en 2 asignaciones de registro y un código de comparación en lenguaje de máquina. El primer ejemplo se dividiría en una asignación y un operador NO. En términos de rendimiento, la operación de comparación tomaría varios ciclos de reloj, dependiendo del tamaño del registro que se compara, en comparación con una inversión a nivel de bits (1 reloj) y sería más lenta de ejecutar.

Dicho esto, creo que los compiladores más nuevos eliminan esto, por lo que debería estar bien con cualquiera.

    
respondido por el lcllam 26.02.2012 - 05:39
1

En el trabajo, a menudo trato con booleanos, que pueden ser nulos, por lo que a menudo codifico este caso como

if (value != null && value == true){
    //do something
}

porque personalmente siento que la simetría hace que sea más fácil de leer. Especialmente si también se están probando otros booleanos.

Realmente no me importa de una manera u otra.

    
respondido por el WuHoUnited 25.02.2012 - 21:52
1

Cuando estás probando la verdadera condición, tiene sentido hacer solo if (condition) , especialmente cuando aplicas la convención de nombrar variables booleanas que comienzan con 'es': if (isOpen) es perfectamente claro y usar != false sería ser redundante

Para un C / C ++ / Java / etc. programador, el significado del '!' El operador está completamente asimilado, hasta el punto de que automáticamente tenemos "no" en nuestras mentes cuando lo vemos. Entonces tener if (!isOpen) es tan claro como if (_NOT_ isOpen) para mí. Pero no está lo suficientemente familiarizado, en C / C ++ podría crear una macro con #define _NOT_ ! . Pero confía en mí, después de unos años esto es completamente innecesario.

Aparte de eso, siempre es preferible probar valores booleanos sin compararlos con literales. Por ejemplo, es peligroso probar if (x == true) porque un valor booleano se considera verdadero si no es cero, y el verdadero literal tiene solo un valor específico, por lo que x podría ser 'verdadero' (es decir, distinto de cero) y aún así la comparación se evalúa como falsa (porque contiene 2 y el verdadero literal es, por ejemplo, 1). Por supuesto, eso no se aplica a una comparación con el falso, pero si no lo usas al probar el verdadero, ¿por qué usarlo al probar el falso?

    
respondido por el Fabio Ceconello 25.02.2012 - 23:16
0

El tamaño importa;)

En expresiones mixtas es más fácil de leer:

boolean1 = false
boolean2 = true

p ! boolean1 and ! boolean2
p boolean1 == false and boolean2 == false

Y especialmente para ruby un ejemplo donde hay una gran diferencia:

boolean = nil
p ! boolean         #-> true
p boolean == false  #-> false

nil no es falso, pero tampoco es cierto.

    
respondido por el knut 25.02.2012 - 22:09
0

Basado en mi experiencia y las respuestas de mi pregunta a las que te has vinculado.

Algunas personas prefieren usar if (condición), porque la razón es más corta para escribir. y para mí realmente tiene sentido, por ejemplo (! isValidated ()) leí esto como No validado. pero para mí todo se basa en preferencias personales y depende de la estructura lógica del método isValidated (), si devuelve verdadero o falso

    
respondido por el KyelJmD 26.02.2012 - 07:47
0

Si nombró su variable correctamente, entonces !boolean es más natural. Se lee como not boolean a cualquiera que tenga suficiente de programador para leer el código mentalmente.

    
respondido por el Lightness Races in Orbit 26.02.2012 - 14:02
0

Para algunas personas, cuanto antes se exprese un significado, mejor.

Para aquellas personas que tienen "if! ..." se compara más rápido que "if ..." y luego tener que leer toda la condición (lo que en realidad podría ser bastante largo, por ejemplo (thisThing = thatThing o algo = la otra cosa) ) O (thinga = thingb y thinga = thingd), etc.) solo para encontrar el == falso al final.

Teniendo el! (De hecho, prefiero un no cuando el idioma lo permite) justo al frente se obtiene el inglés "no" para esta condición antes.

Este problema también lleva a considerar el uso de until en los idiomas que lo admiten, por ejemplo. Hacer 'cosas comunes' hasta que la cosa se complete. Como dicen otros, la expresión del lenguaje natural es la meta. Me gusta el ejemplo de "el sol brilla".

    
respondido por el junky 27.02.2012 - 05:53
0

Otra razón es que si estás trabajando en una base de código que usa varios idiomas, si hay una forma idiomática de hacer algo que sea seguro en todos los idiomas, es una buena idea hacerlo de esa manera en todas partes para que puedas formar un buen hábito y son menos propensos a tropezar.

No puedo pensar en ninguna parte en que if (!variable) (o equivalentes como if not variable según tu idioma) no sea seguro, mientras que, por ejemplo, if self.is_ready() == False: ... no es seguro en python si self.is_ready() devuelve None , ahora o en el futuro, lo cual sería una cosa totalmente razonable para que indique que no estaba listo ya que None es tan falso como False .

    
respondido por el daphtdazz 08.10.2018 - 15:32

Lea otras preguntas en las etiquetas