I am learning the new and very beautiful language Kotlin and everything seems to be very logical and consistent. I only found one thing which seems like an arbitrary exception to the rule than a solid rule. But maybe I lack enough understanding some deeper reasons behind the rule.
I know that in if-else
and when
statements there are blocks of code, then the last expression is returned. In the next example 1
or 2
are returned depending on the condition - in our case it returns 1
.
val x = if (1 < 2) {println("something"); 1} else {println("something else"); 2}
On the other hand this does not hold for any code block. The next line assigns y
not to 1
but to the whole block of code as a lambda.
val y = {println("something"); 1}
Similarly in function body, the last expression is not returned. This does not even compile.
fun z() : Int {
println("something")
1
}
So what exactly is the rule? Is it really so arbitrary like: if in if-else
or when
statement which is used as expression there is a block of code, then the last expression in the block is returned. Otherwise the last expression is not returned to outer scope. Or am I missing something?
Return expressions are denoted with the keyword return . Evaluating a return expression moves its argument into the designated output location for the current function call, destroys the current function activation frame, and transfers control to the caller frame.
A function is a named block of code that has the purpose of returning a value (called the 'return value'). Like a procedure, a function can be called by another part of the program. Consider the following example: Pseudocode.
return@ is a statement in Kotlin which helps the developers to return a function to the called function. In simple words, return@ can return any value, anonymous function, simple inline function, or a lambda function.
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.
you misunderstand the curly brackets {}
, when around with all flow-control
statement it is just a block, for example:
if (condition) { //block here
}
WHEN the {}
is declared separately it is a lambda expression, for example:
val lambda: () -> Int = { 1 }; // lambda
WHEN you want to return a lambda
in if-else
expression, you must double the curly brackets {}
or using parentheses ()
to distinguish between the block and the lambda expression or make the {}
as lambda explicitly, for example:
val lambda1: () -> Int = if (condition) { { 1 } } else { { 2 } };
val lambda2: () -> Int = if (condition) ({ 1 }) else ({ 2 });
val lambda3: () -> Int = if (condition) { -> 1 } else { -> 2 };
If a function does not return any useful value, its return type is
Unit
.Unit
is a type with only one value -Unit
. This value does not have to be returned explicitly.
On the other hand, a common function
must have a explicit return
statement if its return type if not a Unit
:
fun z(): Int { return 1; }
Another case is a function return Nothing
, the return
statement don't allowed at all, because you can't create a Nothing
instance, for example:
fun nothing(): Nothing {
return ?;// a compile error raising
}
WHEN a function has only one expression then you can using single-expression function instead, for example:
fun z() = 1;
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