The difference between && and and and the difference between || and or:
&&and||use short-circuit evaluation whileandandoralways evaluate every condition
But apart from that, I get different behaviour for the following example:
Using &&, this snippet perfectly works:
var str1: String? = "Good Morning"
var str2: String? = "How's it going"
if (str1 != null && str2 != null) {
println(str1.length str2.length)
}
When I replace the && with and I have to add parenthesis around both conditions, otherwise the compiler seems to get confused because I get the error: Operator '!=' cannot be applied to 'String?' and 'BigInteger'
Using and and adding parenthesis:
var str1: String? = "Good Morning"
var str2: String? = "How's it going"
if ((str1 != null) and (str2 != null)) {
println(str1.length str2.length)
}
But this last snippet throws:
Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?
Shouldn't both expressions do precisely the same? Evaluate both conditions and only execute the println when both String values are non-null? What is the difference?
CodePudding user response:
&& is different from and in an additional way in that it introduces a smart cast from String? to String, allowing you to access length by saying str1.length and str2.length, rather than using str1?.length and str2?.length.
From the Kotlin language specification:
Smart casts are introduced by the following Kotlin constructions.
- Conditional expressions (
if)- When expressions (
when);- Elvis operator (operator
?:);- Safe navigation operator (operator
?.);- Logical conjunction expressions (operator
&&);- Logical disjunction expressions (operator
||);- Not-null assertion expressions (operator
!!);- Cast expressions (operator
as);- Type-checking expressions (operator
is);- Simple assignments;
- Platform-specific cases: different platforms may add other kinds of expressions which introduce additional smart cast sources.
You need the extra parenthesis because and, being an infix function, has a higher precedence than &&, which is not an infix function. See all the precedences here.
