2012-03-02 28 views
10

Recientemente descubrí que Java (y Scala) incluyen operadores lógicos sin cortocircuito &, | y ^. Anteriormente pensé que estos solo funcionaban como operadores bit a bit. Aunque tal vez haya un argumento para ^, no puedo pensar en buenas razones para usar operadores lógicos que no sean de cortocircuito, aunque estoy seguro de que puedo dar un ejemplo.¿Hay buenos usos para los operadores lógicos (booleanos) sin cortocircuito en Java/Scala?

¿Estos operadores son útiles? Parece más probable que causen errores difíciles de atrapar.

scala> def foo = { 
    | println("foo") 
    | true 
    | } 
foo: Boolean 

scala> def bar = { 
    | println("bar") 
    | true 
    | } 
bar: Boolean 

scala> foo || bar 
foo 
res5: Boolean = true 

scala> foo | bar 
foo 
bar 
res6: Boolean = true 
+1

No, los operadores bit a bit solo deben usarse para operaciones bit a bit, IMHO :) –

+1

Las únicas respuestas posibles a esta pregunta son ejemplos específicos de "operadores sin cortocircuito son útiles cuando no se desea un cortocircuito". Entonces, la verdadera pregunta es "¿cuándo no quieres un cortocircuito?" –

Respuesta

14

Son útiles si el lado derecho es una función con efectos secundarios que desea ejecutar independientemente (por ejemplo, registro). Sin embargo, sugeriría que es un poco olor a código y sin duda no será intuitivo para el siguiente tipo.

+1

Totalmente de acuerdo, esto no debe hacerse en código real. –

+0

Como dije, puedo hacer un ejemplo artificial ;-) – schmmd

8

Hmm. Sé que pueden ser increíblemente útiles para optimizar el código C/C++ si se usan con cuidado. También podría aplicarse a Java.

El uso principal en C, aparte de las operaciones de bits reales, es eliminar un bloqueo de canalización. Los operadores de cortocircuito requieren una operación de sucursal. El operador bit a bit calculará ambos lados y elimina la posibilidad de una rama mal predicha y la pérdida resultante.

+0

Supongo que tendrías que equilibrar el costo del puesto contra el costo de ejecutar el código que de otro modo no necesitaría ejecutarse/afectar el resultado del programa – dty

+0

@dty: Sí, absolutamente. Tenga en cuenta el "si se usa con cuidado". :-) –

+5

Cuando escribía 'com.google.common.math' de Guava, cuando la segunda condición era particularmente rápida, mis puntos de referencia a veces indicaban que los operadores que no estaban en cortocircuito eran más rápidos que los que estaban en cortocircuito por este motivo. (Dicho esto, no habría hecho ese cambio si no tuviera puntos de referencia muy sólidos y detallados). –

0

Si está tratando de rastrear respuestas o ingresar algo, y eso depende de ambos lados de la ejecución booleana sin cortocircuito.

A modo de ejemplo, supongamos que tiene:

if(methodA() & methodB()){ 
    //some code 
} 

Y dentro del método methodB() un código esencial está en marcha. Si fuera un código de cortocircuito (& &) y methodA() era falso, el método B() nunca se ejecutaría.

Ese es uno de los usos que se me ocurre, al menos.

2

El uso de operadores booleanos sin cortocircuito implica que los operandos tienen efectos secundarios. Si no tenían efectos secundarios, entonces el programador podría haber usado las versiones de cortocircuito sin ningún cambio en la funcionalidad.

En el código escrito en un estilo funcional (que Scala sin duda alienta pero no requiere), los efectos secundarios son una indicación de que algo inusual está sucediendo. Las cosas inusuales deben indicarse claramente en el código, en lugar de algo tan sutil como un operador booleano que no sea de cortocircuito.

Cuestiones relacionadas