pavlos163
pavlos163

Reputation: 2890

Idiomatic way to return if not null in 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
  }
}

Upvotes: 7

Views: 11248

Answers (4)

pabloa98
pabloa98

Reputation: 618

It could be something like:

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

I am assuming the external loop is needed. If that is not the case, Ryba suggested solution should work.

Upvotes: 0

s1m0nw1
s1m0nw1

Reputation: 81859

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

Upvotes: 6

Ryba
Ryba

Reputation: 1299

The "right" idiomatic way of doing this is using the "first" method.

Example:

val x = listOf<Int?>(null, null, 3, null, 8).first { it != null }

His specific example would be

return list.first {getNullableValue(it) != null}

Upvotes: 1

Tim Malseed
Tim Malseed

Reputation: 6353

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
}

Upvotes: 6

Related Questions