2017-01-25 39 views
30

Gdy spróbujesz zrobić coś takiego:Dlaczego działa funkcja (boolean^int> 0)?

if (true^1) { 
    //do something 
} 

kompilator rozsądnie mówi, że operator ^ nie jest zdefiniowane dla typów argumentów boolean i int. Ale jeśli używasz go tak:

if (true^1 > 0) { 
    //do something 
} 

się kompiluje kod (Java 8 co najmniej) i bezawaryjnie działa. Zasadniczo te operacje:

false^-1 > 0 
false^1 > 0 
true^-1 > 0 
true^1 > 0 

działać jak ważny logicznej XOR:

 |^
-----+-- 
F F | F 
F T | T 
T F | T 
T T | F 

Czy ktoś proszę wyjaśnić, co dzieje się pod maską?

+32

Zalecam zapoznanie się z [* priorytetem operatora *] (http://introcs.cs.princeton.edu/java/11precedence/). –

+5

@Someprogrammerdude Aby być uczciwym, fakt, że operatory bitowe mają niższy priorytet niż porównania, jest szczególnie niezrozumiałym aspektem priorytetu operatorów w przypadku języków. – Random832

+5

Dlatego musisz się o tym dowiedzieć, @random :-) –

Odpowiedz

78

To proste: > ma wyższy precedence niż ^, więc

if (true^1 > 0) { 

jest równoważna

if (true^(1 > 0)) { 

co odpowiada

if (true^true) 

... co jest po prostu logiczne XOR.

Nigdy bym nie napisać kod tak, pamiętaj. Byłbym zaskoczony, gdyby zobaczyłem przykład, który nie mógłby być napisany jaśniej w inny sposób.

+3

Nigdy nie zrozumiałem, dlaczego języki zorientowane na bezpieczeństwo, takie jak Java i C#, zezwalają nawet na taki kod, zamiast wymagać nawiasów dla jasności. W końcu nie ma reguły, że pierwszeństwo operatora musi być całkowitym porządkiem. – CodesInChaos

+2

@CodesInChaos: Well predence + associativity sprawiają, że zachowanie jest dobrze zdefiniowane dla każdego wyrażenia. Nie jestem pewien, czy to masz na myśli "całkowite zamówienie" ... –

+3

@CodeInChaos Myślę, że odpowiedź brzmi, że są zorientowane na bezpieczeństwo, a nie na czystość. Są powiązane, ale odrębne. Bezpieczeństwo wymaga, aby nie było dwuznaczności i jest to zdecydowanie jednoznaczne. Idea języka klarowności jest jednak interesująca. Nigdy nie pracowałem z czymś, co ograniczyło składnię _pewnie_, ponieważ może to być trudne do zrozumienia. To dziwne, ponieważ jasność jest powszechnie uważana za tak fundamentalny aspekt dobrego rozwoju. – JimmyJames

10

1 jest typu int.

1> 0 jest typu boolean.

^oznacza XOR; i nie możesz XOR boolean i int.

Innymi słowy: pierwsze wyrażenie "1" oznacza liczbę; drugie wyrażenie "1> 0" odnosi się do logiki Boole'a. Powodem tego jest operator predecence.

11

Ponieważ operacja ma wyższy priorytet niż ^, więc jest równoważna z true^(1>0), która działa z tymi samymi typami (boolean^boolean).

+0

[To jest "niż", a nie "wtedy"] (http://www.wikihow.com/Use-Than-and-Then) (w tym kontekście). –

3

Ponieważ zamówienie (priorytet) operacji jest ważna, > ma wyższy priorytet niż ^

Tutaj, najpierw musimy sprawdzić 1 > 0 a następnie pierwsza operacja jest XORed (^) z pierwszego wyniku

jest równoważna if(true^(1 > 0))

Ale, oczywiście, nie można przeliczyć na wartość boolowską z int