Have you ever encountered a situation when you want to write a function that returns a value after some calculations, Or when you need to jump the control to the caller of function etc.? In this article, we will discuss about such scenarios. We will discuss how to deal with above scenarios in kotlin programming language. Above scenarios can easily be achieved using return or labeled return in kotlin.
In this article, we will learn about how to use return in kotlin programming language. For example, returning from function or anonymous function or inline function, returning from a lambda expression etc.
Please note that we would be talking about 2 types of return in kotlin in this article –
1. Unlabeled return in kotlin
2. Labeled return in kotlin
Let’s go through each one by one.
1. Unlabeled return in kotlin
Unlabeled return, or simply return, returns from the nearest enclosing function. It is represented by return keyword. We just write return or return value. value can be string, int, float, object etc.
Let’s take an example,
fun main(args: Array<String>) { val s = name() println("Name = $s") } fun name() : String { return "Tutorialwing" }
Explanation: We have defined a method name that always returns string (“Tutorialwing”) to the caller. So, variable s will be assigned a String “Tutorialwing” returned by method name(). So, output will be
2. Labeled return in kotlin
Labeled return: Using this return, control of the program is returned to the specified line in the program. This can be used as return@labelname or return@labelname value. It means return to the position labeled as labelname with the value provided. Note that there is no space between return@ and labelname.
Let’s take an example,
fun main(args: Array<String>) { foo(listOf(1,0,3,4)) } fun foo(ints: List<Int>) { ints.forEach inner@ { if (it == 0) return@inner println(it) } println("Hii there") }
When you run the program, you will get below output:
1
3
4
Hii there
Explanation: return@inner will cause the program to jump it’s control to label inner. In this program, we are checking each time if the value inside forEach loop is 0 or not. If it is 0, control is being returned to label inner@.
Till now, we have gone through a brief introductions about return or labeled return in kotlin. Now, we will see different scenarios where it can be used.
Different scenarios where return or labeled return is used –
a. Function
b. Lambda expression
a. How to use return in Function
Here, we will talk about use of return in function. return statement in function causes the control of the program to return from that function to the caller of the function. For example,
fun main(args: Array<String>) { val product = multiply(3,5) println("product = $product") } fun multiply(first: Int, second: Int) : Int { return first * second; }
output is :
product = 15
Explanation: Here, multiply method returns the product of two numbers passed as parameters. We are calling this method with parameter 3 and 5 from main method. So, multiply method will return 15 that is stored in variable product. So, output will be product = 15.
Note: Note that we have mentioned the data type of the value being returned by the function after it’s parameter. We have written fun multiply(first: Int, second: Int) : Int . Last Int represents the data type of the value being returned by the function.
Unit return from function
If a function does not return any useful value, it’s return type us Unit. Unit is a type with only one value – Unit. We do not need to return it explicitly from function. However, i am giving an example below just to make things clearer.
fun main(args: Array<String>) { hello("Rajeev"); } fun hello(name: String): Unit { println(name) return Unit }
Notice that we have mentioned return type is Unit. In the last line of the function hello, we have also returned Unit. However, This is optional.
A simpler version of above program is given below.
fun main(args: Array<String>) { hello("Rajeev"); } fun hello(name: String): Unit { println(name) return }
Notice that we have omitted Unit in the last line.
Guess what! you can omit writing data type of returned value or writing return statement if you want to return Unit value. So, a more simpler version of above program would be –
fun main(args: Array<String>) { hello("Rajeev"); } fun hello(name: String) { println(name) }
Notice that we have neither written return statement nor mentioned the data type of returned value in hello method. Compiler by default assumes Unit return value. So, you do not need to mention it.
So, All the above 3 examples are same.
Single expression return in Function
If a function returns a single expression, curly braces can be omitted and the body of the function is written after = symbol. For example,
fun main(args: Array<String>) { val num = 3 val squareValue = square(num); println("Square of $num is $squareValue") } fun square(x: Int): Int { return x * x; }
The above example can be re-written as below
fun main(args: Array<String>) { val num = 3 val squareValue = square(num); println("Square of $num is $squareValue") } fun square(x: Int): Int = x * x;
Notice that we have removed curly brackets and the body of the function is written after = symbol.
You can also remove explicitly declaring data type of returned value because it is inferred from the returned value by compiler. So, above program can be more simplified as below
fun main(args: Array<String>) { val num = 3 val squareValue = square(num); println("Square of $num is $squareValue") } fun square(x: Int) = x * x;
Note: Function with block body must always specify return type explicitly, unless return type is Unit, because control flows inside the body may be complex.
1. Guess the output of below program.
fun main(args: Array<String>) { val returnedVal = outer(); if(returnedVal == 1) { println("Returned From Outer Function") } else { println("Returned From Inner Function inside Outer Function") } } fun outer(): Int { fun inner(i: Int) { if(i < 0) return println("Hii There"); } inner(-1) inner(4) return 1 }
b. How to use return in lambda expression in kotlin
When unlabeled return is used with lambda expression, it returns from nearest enclosing function. For example,
fun main(args: Array<String>) { foo(listOf(1,2,0,4)) } fun foo(ints: List<Int>) { ints.forEach { if (it == 0) return println(it) } println("Hi there") }
Output:
1
2
In above example, return statements causes the control of the program to jump from that line to the caller of the function foo() i.e. This is non-local return from inside lambda expression directly to the caller of the function foo().
Labeled return in lambda expression
If you want to return from lambda expression rather than nearest enclosing function, you will have to use labeled return statement. For example,
fun main(args: Array<String>) { foo(listOf(1,2,0,4)) } fun foo(ints: List<Int>) { ints.forEach inner@ { if (it == 0) return@inner println(it) } println("Hi there") }
Output:
1
2
4
Hi there
In the above example, when value if it will be 0, return@inner will cause the control of the program to return to label inner@.
Above example can be re-written using implicit labels. Such label has same name as the function to which the lambda is passed. So, above example using implicit label is
fun main(args: Array<String>) { foo(listOf(1,2,0,4)) } fun foo(ints: List<Int>) { ints.forEach { if (it == 0) return@forEach println(it) } println("Hi there") }
Output:
1
2
4
Hi there
Return in Anonymous function in kotlin
If you do not want to use lambda expression, you can replace it with anonymous function.
In anonymous function, you do not need labeled return. A return statement in anonymous function will return from
the anonymous function itself. For example,
Above program can be re-written using anonymous function as below.
fun main(args: Array<String>) { foo(listOf(1,2,0,4)) } fun foo(ints: List<Int>) { ints.forEach(fun (it) { if(it == 0) return println(it) }) println("Hii there!") }
Output:
1
2
4
Hi there
Conclusion
In this post, we have seen how to use return in Kotlin in different scenarios. We have see various examples that demonstrates the use of return or labeled return in function or in lambda expression.