16
votes

I want to negate the following expression:

return SpUtils.loadEMail()?.isEmpty() ?: false

If i add a ! before the expression, like

return !SpUtils.loadEMail()?.isEmpty() ?: false

The IDE(Android Studio) tells me

Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type kotlin.Boolean?

How do I negate this kinds of expressions?

3
As a side note, there is also the .not() function which you can use with the safe call operator, e.g. SpUtils.loadEMail()?.isEmpty()?.not()Kirill Rakhman

3 Answers

11
votes

You have problem with nullable reference.

 SpUtils.loadEMail()?.isEmpty()

This code produces value of type Boolean? that's mean expression can return an instance of Boolean or null.

I suggest following code to solve your problem:

return !(SpUtils().loadEMail()?.isEmpty() ?: false);

You trying negate Boolean? instead of Boolean, that elvis operator returns!

3
votes

?. is a safe call operator.

In this case it returns you:

  • boolean value if the result of loadEmail() invocation is not null
  • null otherwise

! is a built-in boolean operation which invokes the package.Boolean's operator called not() which works only on non-nullable references. The result of ?. is Boolean?, thus you get your error.

If you want to negate the whole expression, you can stick to the iRus answer:

!(SpUtils().loadEMail()?.isEmpty() ?: false)

If you want to negate just the SpUtils().loadEMail()?.isEmpty() part then the correct variant will be:

!(SpUtils().loadEMail()?.isEmpty() ?: true)

If the result of ?. will be null (there is no mail) then the elvis operator will return you true (no e-mail) and you'll negate it.

1
votes

!(SpUtils().loadEMail()?.isEmpty() ?: false) would work, but it's really difficult to see when this would actually return true.

It returns true when the result of SpUtils().loadEMail() is null or not empty. With this knowledge, we can easily make something readable:

return SpUtils().loadEMail()?.isNotEmpty() ?: true

You can expand it for even better readability:

val email = SpUtils().loadEMail()
if (email == null || email.isNotEmpty()) {
    return true
}
return false