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] }
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With