I've been a Java Developer for many years and recently I've found something very suprising in Kotlin. In Java there is a rarely used logical operator ^
XOR but sometimes it's useful. For example: you can easly check if one and only one of two numbers is greater than zero.
With &&
AND operator and some variables a
and b
it looks like that:
boolean valid = (a > 0 && b <= 0) || (a <= 0 && b > 0);
but it can easly achieve with ^
XOR:
boolean valid = a > 0 ^ b > 0;
Now, in Kotline we don't use ^
as a XOR but just xor
and same code in Kotlin looks like that:
val valid = a > 0 xor b > 0;
And here comes a problem because this code in Kotline gives ... compilation error!! Why? Because in Java all logical operator (&,&&,|,||,^
) got lower precedence than relational operators (>, >=, <, <=, ==, !=
). Same in Koltin but it looks like not for xor
. So it goes this way:
a > 0
gives boolean valueboolean xor b > 0
first evealuated to: boolean xor b
not b > 0
The integer literal does not conform to the expected type Boolean
You can check this situation here: XOR not working well
One extra case: if you think that this one: a > 0 xor (b > 0)
works... well, no. Another compilation error: Type mismatch: inferred type is Boolean but Int was expected
Can anyone explain me is there some purpouse for such logic or it's just a bug in Kotlin language?
xor
is not an operator, but an
infix function. Infix function calls have higher precedence than the comparison. Expressions
val valid = a > 0 xor b > 0
is the same as val valid = a > (0 xor b) > 0
(0 xor b)
gives Int valuea > (0 xor b)
gives Boolean value(step 2 Boolean result) > 0
), but you cannot compare Boolean with IntCorrect version:
val valid = (a > 0) xor (b > 0)