Personalmente, me gusta el operador exclusivo o , ^
cuando tiene sentido en el contexto de los controles booleanos debido a su concisión. Prefiero escribir
if (boolean1 ^ boolean2)
{
//do it
}
que
if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
//do it
}
pero a menudo recibo miradas confusas de otros desarrolladores de Java experimentados (no solo los novatos), y a veces comenta sobre cómo solo debe usarse para operaciones bit a bit.
Tengo curiosidad sobre las mejores prácticas con respecto al uso del ^
operador.
bool1 ^ bool2 ^ bool3
bool1 != bool2 != bool3
!=
produce resultados correctos paraboolean
s (pero no paraBoolean
s, así que tenga cuidado). Sin embargo, no siempre es bonito, por ejemplo,(some != null) != (other != null)
no es muy legible. Debe extraer las partes en booleanos explícitos o extraerlas!=
en un método separado.a ^ b
=> "aob pero no ambos",a != b
=> "a no es igual a b". (Lo que dijo @RobertGrant). La mayoría de los humanos entenderían el primero más fácilmente si supieran qué es xor (lo cual es bastante útil saber si estás en el campo de la informática ...)a != b
=> "a no es IDÉNTICO para b"Creo que has respondido tu propia pregunta: si obtienes miradas extrañas de la gente, probablemente sea más seguro optar por la opción más explícita.
Si necesita comentarlo, entonces probablemente sea mejor reemplazarlo con la versión más detallada y no hacer que la gente haga la pregunta en primer lugar.
fuente
(boolean1 && !boolean2) || (boolean2 && !boolean1)
un código de aplicación de la vida real ...Me parece que tengo muchas conversaciones similares. Por un lado, tiene un método compacto y eficiente para lograr su objetivo. Por otro lado, tiene algo que el resto de su equipo podría no entender, lo que dificulta su mantenimiento en el futuro.
Mi regla general es preguntar si la técnica utilizada es algo que es razonable esperar que los programadores en general sepan. En este caso, creo que es razonable esperar que los programadores sepan cómo usar operadores booleanos, por lo que usar xor en una declaración if está bien.
Como ejemplo de algo que no estaría bien, tome el truco de usar xor para intercambiar dos variables sin usar una variable temporal. Ese es un truco con el que no esperaría que todos estén familiarizados, por lo que no pasaría la revisión del código.
fuente
Creo que estaría bien si lo comentaras, por ejemplo
// ^ == XOR
.fuente
Siempre puedes envolverlo en una función para darle un nombre detallado:
Pero, me parece que no sería difícil para cualquiera que no supiera para qué sirve el operador ^, para que Google sea realmente rápido. No será difícil de recordar después de la primera vez. Como solicitó otros usos, es común usar el XOR para el enmascaramiento de bits.
También puede usar XOR para intercambiar los valores en dos variables sin usar una tercera variable temporal .
Aquí hay una pregunta de Stackoverflow relacionada con el intercambio de XOR .
fuente
Recientemente utilicé un xor en un proyecto de JavaScript en el trabajo y terminé agregando 7 líneas de comentarios para explicar lo que estaba sucediendo. La justificación para el uso de xor en ese contexto fue que uno de los términos (
term1
en el ejemplo de abajo) podría asumir no dos, sino tres valores:undefined
,true
ofalse
mientras que el otro (term2
) podría sertrue
ofalse
. Hubiera tenido que agregar una verificación adicional para losundefined
casos, pero con xor, lo siguiente fue suficiente, ya que xor obliga al primer término a ser evaluado por primera vez como booleano, permitiendo queundefined
se lo trate comofalse
:Al final, fue un poco exagerado, pero de todos modos quería mantenerlo allí, como una especie de huevo de pascua.
fuente
bool? a
valor puede probarse explícitamente para el uso verdaderoa == true
: ¿existe una técnica similar en Java? En C #, dados dosbool?
valores, "tratar nulo como falso" conduciría a(a == true) ^ (b == true)
. Una fórmula equivalente es(a == true) != (b == true)
. ¿Se puede hacer algo similar en Java?En mi humilde opinión este código podría simplificarse:
fuente
Con la claridad del código en mente, mi opinión es que usar XOR en comprobaciones booleanas no es un uso típico para el operador XOR bitwise. Según mi experiencia, el XOR bit a bit en Java se usa típicamente para implementar un
flag toggle
comportamiento de máscara :Este artículo de Vipan Singla explica el caso de uso con más detalle.
Si necesita usar XOR bit a bit como en su ejemplo, comente por qué lo usa, ya que es probable que incluso un público alfabetizado bit a bit se detenga para comprender por qué lo está utilizando.
fuente
Personalmente prefiero la expresión "boolean1 ^ boolean2" debido a su brevedad.
Si estuviera en su situación (trabajando en equipo), llegaría a un compromiso encapsulando la lógica "boolean1 ^ boolean2" en una función con un nombre descriptivo como "isDifferent (boolean1, boolean2)".
Por ejemplo, en lugar de usar "boolean1 ^ boolean2", llamaría "isDifferent (boolean1, boolean2)" de esta manera:
Su función "isDifferent (boolean1, boolean2)" se vería así:
Por supuesto, esta solución implica el uso de una llamada a una función aparentemente extraña, que en sí misma está sujeta al escrutinio de las Mejores Prácticas, pero evita la expresión detallada (y fea) "(boolean1 &&! Boolean2) || (boolean2 &&! Boolean1) "!
fuente
Si el patrón de uso lo justifica, ¿por qué no? Si bien su equipo no reconoce al operador de inmediato, con el tiempo podrían hacerlo. Los humanos aprenden nuevas palabras todo el tiempo. ¿Por qué no en programación?
La única precaución que podría decir es que "^" no tiene la semántica de cortocircuito de su segunda verificación booleana. Si realmente necesita la semántica de cortocircuito, también funciona un método de utilidad estático.
fuente
xor
, que hace exactamente lo que hace el operador xor pero de forma indirecta, me plantearía más preguntas (específicamente sobre la competencia) que un programador que acaba de usar^
.! = está bien para comparar dos variables. Sin embargo, no funciona con múltiples comparaciones.
fuente
Como operador bit a bit, xor es mucho más rápido que cualquier otro medio para reemplazarlo. Entonces, para cálculos críticos y escalables de rendimiento, xor es imprescindible.
Mi opinión personal subjetiva: está absolutamente prohibido, por cualquier motivo, utilizar la igualdad (== o! =) Para los booleanos. Su uso muestra falta de ética y fundamentos básicos de programación. Cualquiera que te dé miradas confusas ^ debería ser enviado de vuelta a los conceptos básicos del álgebra booleana (tuve la tentación de escribir "a los ríos de creencias" aquí :)).
fuente
se ve mejor para mí que
fuente