best way to null check in kotlin?

2019-01-23 01:12发布

问题:

Should I use double =, or triple =?

if(a === null)  {
//do something
}

or

if(a == null)  {
//do something
}

Similarly for 'not equals':

if(a !== null)  {
//do something
}

or

if(a != null)  {
//do something
}

回答1:

Both approaches generate the same bytecode so you can choose whatever you prefer.



回答2:

A structural equality a == b is translated to

a?.equals(b) ?: (b === null)

Therefore when comparing to null, the structural equality a == null is translated to a referential equality a === null.

According to the docs, there is no point in optimizing your code, so you can use a == null and a != null


Note that if the variable is a mutable property, you won't be able to smart cast it to its non-nullable type inside the if statement (because the value might have been modified by another thread) and you'd have to use the safe call operator with let instead.

Safe call operator ?.

a?.let {
   // not null do something
   println(it)
   println("not null")
}


You can use it in combination with the Elvis operator.

Elvis operator ?: (I'm guessing because the interrogation mark looks like Elvis' hair)

a ?: println("null")

And if you want to run a block of code

a ?: run {
    println("null")
    println("The King has left the building")
}

Combining the two

a?.let {
   println("not null")
   println("Wop-bop-a-loom-a-boom-bam-boom")
} ?: run {
    println("null")
    println("When things go null, don't go with them")
}


回答3:

Check useful methods out, it could be useful:

/**
 * Performs [R] when [T] is not null. Block [R] will have context of [T]
 */
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
    return input?.let(callback)
}

/**
 * Checking if [T] is not `null` and if its function completes or satisfies to some condition.
 */
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
    return ifNotNull(this) { it.run(check) } ?: false
}

Below is possible example how to use those functions:

var s: String? = null

// ...

if (s.isNotNullAndSatisfies{ isEmpty() }{
   // do something
}


回答4:

Addition to @Benito Bertoli,

the combination is actually unlike if-else

"test" ?. let {
    println ( "1. it=$it" )
} ?: let {
    println ( "2. it is null!" )
}

The result is:

1. it=test

But if:

"test" ?. let {
    println ( "1. it=$it" )
    null // finally returns null
} ?: let {
    println ( "2. it is null!" )
}

The result is:

1. it=test
2. it is null!

Also, if use elvis first:

null ?: let {
    println ( "1. it is null!" )
} ?. let {
    println ( "2. it=$it" )
}

The result is:

1. it is null!
2. it=kotlin.Unit