Using return inside a lambda?

In the code below, I want to show my empty views if trips is empty and then return and avoid running the below code, but the compiler says "return is not allowed here".

mainRepo.fetchUpcomingTrips { trips ->
    if (trips.isEmpty()) {
        showEmptyViews()
        return
    }

    // run some code if it's not empty
}

Is there a way to return like that?

I know I can just put it in an if else block but I hate writing if else's, it's less understandable/readable in my opinion when there's a few more conditions.


Solution 1:

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 can use the name of the function the lambda is passed to (fetchUpcomingTrips) as the label:

mainRepo.fetchUpcomingTrips { trips ->
    if (trips.isEmpty()) {
        showEmptyViews()
        return@fetchUpcomingTrips 
    }

    // ...
}

Related:

  • Return at labels in the language reference

  • Whats does “return@” mean?

Solution 2:

You can also replace { trips -> with fun(trips) { to form an anonymous function which can use return normally.

Solution 3:

Plain return suggests that you return from the function. Since you can't return from the function inside a lambda, the compiler will complain. Instead, you want to return from the lambda, and you have to use a label:

mainRepo.fetchUpcomingTrips { trips ->
    if (trips.isEmpty()) {
        showEmptyViews()
        return@fetchUpcomingTrips
    }

    //run some code if it's not empty
}