Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Idiomatic way to return if not null in Kotlin

Tags:

kotlin

I am looking for an idiomatic way to return if not null a variable in Kotlin. For example, I would like something such as:

for (item in list) {
  getNullableValue(item).? let {
    return it
  }
}

But it's not possible to return inside a let block in Kotlin.

Is there a good way to do this without having to do this:

for (item in list) {
  val nullableValue = getNullableValue(item)
  if (nullableValue != null) {
    return nullableValue
  }
}
like image 885
pavlos163 Avatar asked Sep 04 '17 00:09

pavlos163


People also ask

How does Kotlin check not null?

You can use the "?. let" operator in Kotlin to check if the value of a variable is NULL. It can only be used when we are sure that we are refereeing to a non-NULL able value.

IS NOT NULL in if condition?

The IS NOT NULL condition is used in SQL to test for a non-NULL value. It returns TRUE if a non-NULL value is found, otherwise it returns FALSE. It can be used in a SELECT, INSERT, UPDATE, or DELETE statement.

What does ?: Mean in Kotlin?

This is a binary expression that returns the first operand when the expression value is True and it returns the second operand when the expression value is False. Generally, the Elvis operator is denoted using "?:", the syntax looks like − First operand ?: Second operand.

How do I return a null value in Kotlin?

In Kotlin, there are optional types. If you return ServiceChargeMasterList, you say to the compiler that you will never return null. If you want to return null, you have to add ? sign at the end of the type which indicates that you can return an instance of ServiceChargeMasterList or null.


2 Answers

It is possible to return from let, as you can read in the documentation:

The return-expression returns from the nearest enclosing function, i.e. foo. (Note that such non-local returns are supported only for lambda expressions passed to inline functions.)

let() is an inline function and therefore you automatically return from the enclosing function whenever you do return within let, like in this example:

fun foo() {
    ints.forEach {
        if (it == 0) return  // nonlocal return from inside lambda directly to the caller of foo()
        print(it)
    }
 }

To modify the behavior, "labels" can be used:

fun foo() {
    ints.forEach lit@ {
        if (it == 0) return@lit
        print(it)
    }
}
like image 103
s1m0nw1 Avatar answered Sep 22 '22 01:09

s1m0nw1


Not sure if this would be called idiomatic, but you could do this:

val nullableValue = list.find { it != null }
if (nullableValue != null) {
    return nullableValue
}

Edit:

Based on s1m0nw1's answer, you can probably reduce it to this:

list.find { it != null }?.let {
    return it
}
like image 38
Tim Malseed Avatar answered Sep 23 '22 01:09

Tim Malseed