Czy dobrą praktyką jest używanie operatora xor do sprawdzania logicznego?

Ja osobiście lubię exclusive lub, ^, operator, gdy ma to sens w kontekście sprawdzeń logicznych ze względu na jego zwięzłość. Wolę pisać

if (boolean1 ^ boolean2)
{
  //do it
}

Niż

if((boolean1 && !boolean2) || (boolean2 && !boolean1))
{
  //do it
}

Ale często mam mylone spojrzenia od innych doświadczonych programistów Java (nie tylko początkujących), a czasami komentarze o tym, jak to powinno być używane tylko do operacji bitowych.

Jestem ciekaw najlepszych praktyk dotyczących korzystania z ^ operatora.

Author: nbro, 2008-10-02

13 answers

Możesz po prostu użyć !=.

 285
Author: vaxquis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-20 20:29:34

Myślę, że odpowiedziałeś na swoje pytanie - jeśli masz dziwne spojrzenia od ludzi, prawdopodobnie bezpieczniej jest wybrać bardziej wyraźną opcję.

Jeśli chcesz to skomentować, to prawdopodobnie lepiej zastąpić go bardziej wyrazistą wersją i nie zmuszać ludzi do zadawania pytania w pierwszej kolejności.

 27
Author: Martin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 03:34:54

Uważam, że często mam podobne rozmowy. Z jednej strony masz kompaktową, skuteczną metodę osiągnięcia celu. Z drugiej strony masz coś, czego reszta twojego zespołu może nie zrozumieć, co utrudnia utrzymanie tego w przyszłości.

Moją ogólną zasadą jest pytanie, czy używana technika jest czymś, czego można oczekiwać od programistów w ogóle. W tym przypadku uważam, że rozsądne jest oczekiwanie od programistów, aby wiedzieli, jak używać operatory logiczne, więc używanie XOR w instrukcji if jest w porządku.

Jako przykład czegoś, co nie byłoby w porządku, weźmy sztuczkę użycia xor do zamiany dwóch zmiennych bez użycia zmiennej tymczasowej. To jest sztuczka, której nie spodziewałbym się, że wszyscy będą zaznajomieni, więc nie przejdzie przeglądu kodu.

 16
Author: Dave Tarkowski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 20:23:20

Myślę, że byłoby w porządku, gdybyś to skomentował, np. // ^ == XOR.

 14
Author: Dre,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 20:18:38

Zawsze możesz owinąć go w funkcję, aby nadać mu wyrazistą nazwę:

public static boolean XOR(boolean A, boolean B) {
    return A ^ B;
}

Ale wydaje mi się, że nie byłoby trudno każdemu, kto nie wiedział, do czego służy operator^, szybko go wygooglować. To nie będzie trudne do zapamiętania po pierwszym razem. Ponieważ poprosiłeś o inne zastosowania, powszechne jest używanie XOR do maskowania bitów.

Możesz również użyć XOR do zamiany wartości w dwóch zmiennych bez użycia trzeciej tymczasowej zmienna .

// Swap the values in A and B
A ^= B;
B ^= A;
A ^= B;

Oto pytanie związane z wymianą XOR .

 8
Author: Cory Gross,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-21 13:45:20

Ostatnio użyłem xor w projekcie JavaScript w pracy i skończyło się dodaniem 7 linijek komentarzy , aby wyjaśnić, co się dzieje. Uzasadnieniem użycia xor w tym kontekście było to, że jeden z terminów (term1 w poniższym przykładzie) może przyjmować nie dwie, ale trzy wartości: undefined, true lub false podczas gdy inne (term2) może być true lub false. Musiałbym dodać dodatkowy czek dla undefined przypadków, ale w przypadku XOR wystarczy, ponieważ XOR wymusza pierwsze termin, który ma być najpierw oceniony jako Boolean, pozwalając {[2] } być traktowanym jako false:

if (term1 ^ term2) { ...
W końcu to była przesada, ale i tak chciałem ją tam zatrzymać, jako rodzaj pisanki.
 6
Author: Ates Goral,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 20:27:21

Mając na uwadze przejrzystość kodu, moim zdaniem używanie XOR w kontrolkach logicznych nie jest typowym zastosowaniem operatora bitowego XOR. Z mojego doświadczenia wynika, że bitowy XOR w Javie jest zazwyczaj używany do implementacji zachowania maski flag toggle:

flags = flags ^ MASK;

Ten artykuł autorstwa Vipana singli wyjaśnia bardziej szczegółowo przypadek użycia.

Jeśli chcesz użyć bitowego XOR, jak w twoim przykładzie, skomentuj, dlaczego go używasz, ponieważ prawdopodobnie będzie to wymagało nawet bitowej czytelnej publiczności, aby zatrzymać się w ich śledzi, aby zrozumieć, dlaczego go używasz.

 5
Author: Gunnar Karlsson,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-22 20:21:19
if((boolean1 && !boolean2) || (boolean2 && !boolean1)) 
{ 
  //do it 
} 

IMHO ten kod można uprościć:

if(boolean1 != boolean2) 
{ 
  //do it 
} 
 4
Author: Y--,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-10 08:33:35

Jeśli wzorzec użycia uzasadnia to, dlaczego nie? Chociaż twój zespół nie rozpoznaje operatora od razu, z czasem może. Ludzie uczą się nowych słów cały czas. Dlaczego nie w programowaniu?

Jedyną ostrożnością, którą mogę stwierdzić jest to, że " ^ " nie ma semantyki zwarcia twojego drugiego sprawdzania logicznego. Jeśli naprawdę potrzebujesz semantyki zwarcia, wtedy działa również statyczna metoda util.

public static boolean xor(boolean a, boolean b) {
    return (a && !b) || (b && !a);
}
 -1
Author: Alan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-02 03:08:30

Osobiście preferuję wyrażenie "boolean1 ^ boolean2" ze względu na jego zwięzłość.

Gdybym był w twojej sytuacji (pracując w zespole), osiągnąłbym kompromis, zamykając logikę "boolean1 ^ boolean2" w funkcji o nazwie opisowej, takiej jak "isDifferent(boolean1, boolean2)".

Na przykład, zamiast używać "boolean1 ^ boolean2", można wywołać "isDifferent(boolean1, boolean2)" w następujący sposób:

if (isDifferent(boolean1, boolean2))
{
  //do it
}

Twoja funkcja" isDifferent(boolean1, boolean2)" wyglądałoby tak:

private boolean isDifferent(boolean1, boolean2)
{
    return boolean1 ^ boolean2;
}

Oczywiście, to rozwiązanie pociąga za sobą użycie pozornie obcego wywołania funkcji, które samo w sobie jest przedmiotem analizy najlepszych praktyk, ale unika się wyrazistego(i brzydkiego) wyrażenia "(boolean1 && !boolean2) / / (boolean2 && !boolean1)"!

 -1
Author: ONE,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-12 04:39:17

!= można porównać dwie zmienne. To jednak nie działa, z wieloma porównaniami.

 -3
Author: ,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-05 10:13:25
str.contains("!=") ^ str.startsWith("not(")

Wygląda dla mnie lepiej niż

str.contains("!=") != str.startsWith("not(")
 -3
Author: Chris Rea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 13:07:45

Jako operator bitowy, xor jest znacznie szybszy niż jakikolwiek inny sposób jego zastąpienia. Tak więc w przypadku obliczeń o krytycznym znaczeniu i skalowalności xor jest niezbędny.

Moja subiektywna opinia: absolutnie zabronione jest, w jakimkolwiek celu, używanie równości (==or != ) dla booleanów. Używanie go wykazuje brak podstawowych zasad i podstaw programowania. Każdy, kto daje mylone spojrzenia ^ należy odesłać z powrotem do podstaw algebry Boole ' a (skusiłem się napisać "do rzek z wiara " tutaj:)).

 -3
Author: Nick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-24 16:44:09