ChatGPT解决这个技术问题 Extra ChatGPT

Best way to null check in Kotlin?

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
}
have look on link :- kotlinlang.org/docs/reference/null-safety.html .............. It easy in Kotlin Docs

B
Benito Bertoli

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")
}

why don't you use if for null checks? a?.let{} ?: run{} is only appropriate in rare cases, otherwise it is not idiomatic
@voddan I wasn't suggesting not using if for null checks, I was listing other viable options. Although I'm not sure if run has some kind of performance penalty. I'll update my answer to make it more clear.
@voddan If a is a var, then using the a?.let{} ?: run{} guarantee that it will be bound properly in the let for the whole scope. If a is a val, then there is no difference.
@madeinqc if a is a val, then using let is different and it's bad. I found this article very good at explaining it - Kotlin: Don’t just use LET for null check.
@voddan I'm new to Kotlin. Would you please explain or provide a URL noting how this is not idiomatic?
L
Levon Petrosyan

Kotlin ways of handling null

Secure Access Operation

val dialog : Dialog? = Dialog()
dialog?.dismiss()  // if the dialog will be null,the dismiss call will be omitted

Let function

user?.let {
  //Work with non-null user
  handleNonNullUser(user)
}

Early exit

fun handleUser(user : User?) {
  user ?: return //exit the function if user is null
  //Now the compiler knows user is non-null
}

Immutable shadows

var user : User? = null

fun handleUser() {
  val user = user ?: return //Return if null, otherwise create immutable shadow
  //Work with a local, non-null variable named user
}

Default value

fun getUserName(): String {
 //If our nullable reference is not null, use it, otherwise use non-null value 
 return userName ?: "Anonymous"
}

Use val instead of var

val is read-only, var is mutable. It’s recommended to use as many read-only properties as you can, they are thread-safe.

Use lateinit

Sometimes you can’t use immutable properties. For example, it happens on Android when some property is initialized in onCreate() call. For these situations, Kotlin has a language feature called lateinit.

private lateinit var mAdapter: RecyclerAdapter<Transaction>

override fun onCreate(savedInstanceState: Bundle?) {
   super.onCreate(savedInstanceState)
   mAdapter = RecyclerAdapter(R.layout.item_transaction)
}

fun updateTransactions() {
   mAdapter.notifyDataSetChanged()
}

I'd call the last one "default value" (not elvis), since 3/4 of those are using elvis.
@AjahnCharles makes sense ))
this is garbage, any language modern can deal better with optionals than this. its more a chore than a benefit for programmers.
M
Michael

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


If i understood it correctly then he is asking for best way to check null in Kotlin, not which approach generates best byte-code.@BenitoBertoli answer looks promising, it's reduces boilerplate code
B
BingLi224

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

V
Vlad

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
}