Home > OS >  Null check with logical operator 'and' throws error while '&&' doesn't in K
Null check with logical operator 'and' throws error while '&&' doesn't in K

Time:11-05

The difference between && and and and the difference between || and or:

  • && and || use short-circuit evaluation while
  • and and or always evaluate every condition

Kotlin doc for "and"

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.

  • Related