Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implicit return from lambda in Kotlin

Tags:

kotlin

It seems that the last line of a lambda always returns that value even if you omit the return statement. Is this correct? Is it documented anywhere?

fun main(args: Array<String>) {     val nums = arrayOf(1, 2, 3)     val numsPlusOne = nums.map { it ->          val r = it + 1         r     }     // numsPlusOne = [2, 3, 4] } 
like image 203
Will Avatar asked Jan 12 '17 19:01

Will


People also ask

Does Kotlin have implicit return?

Yes, this is correct, if the last statement of a lambda is an expression, it is considered its return value. So, lambdas are consistent with the language constructs in this respect.

How do I return from lambda expression to Kotlin?

Just use the qualified return syntax: return@fetchUpcomingTrips . In Kotlin, return inside a lambda means return from the innermost nesting fun (ignoring lambdas), and it is not allowed in lambdas that are not inlined. The return@label syntax is used to specify the scope to return from.

What is () -> unit in Kotlin?

Unit in Kotlin corresponds to the void in Java. Like void, Unit is the return type of any function that does not return any meaningful value, and it is optional to mention the Unit as the return type. But unlike void, Unit is a real class (Singleton) with only one instance.

How do you use lambda expression in Kotlin?

A lambda expression is always surrounded by curly braces, argument declarations go inside curly braces and have optional type annotations, the code_body goes after an arrow -> sign. If the inferred return type of the lambda is not Unit, then the last expression inside the lambda body is treated as return value.


1 Answers

Yes, this is correct, if the last statement of a lambda is an expression, it is considered its return value.

Here's what the reference says (thanks @KirillRakhman):

We can explicitly return a value from the lambda using the qualified return syntax. Otherwise, the value of the last expression is implictly returned. Therefore, the two following snippets are equivalent:

ints.filter {     val shouldFilter = it > 0      shouldFilter } 

ints.filter {     val shouldFilter = it > 0      return@filter shouldFilter } 

The last statement semantics is also true for if (that's why there's no ternary operator), when and try-catch blocks, and these statements are expressions themselves:

val foo = if (bar) {      doSomething()     baz  } else {      doSomethingElse()     qux  } 

See also: examples for when and try-catch.

So, lambdas are consistent with the language constructs in this respect.


If you want to make an explicit return statement in a lambda, use the return@label syntax (also, another answer with examples). Non-labeled return, on contrary, works with the nearest fun (ignoring lambdas) and thus can only occur in those lambdas which are inlined.

There was a language proposal to add special syntax for emitting a value from a code block, but it was rejected.

like image 99
hotkey Avatar answered Sep 25 '22 19:09

hotkey