Using return inside a lambda?

2019-02-21 08:29发布

问题:

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.

回答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?



回答2:

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
        }


回答3:

The returns allow us to return from an outer function. The most important use case is returning from a lambda expression

A return statement in an anonymous function will return from the anonymous function itself.

fun foo() {
ints.forEach(fun(value: Int) {
    if (value == 0) return  // local return to the caller of the anonymous fun, i.e. the forEach loop
    print(value)
})
}

When returning a value, the parser gives preference to the qualified return, i.e.

return@a 1

means "return 1 at label @a" and not "return a labeled expression (@a 1)". Return By default returns from the nearest enclosing function or anonymous function.

Break Terminates the nearest enclosing loop.

Continue Proceeds to the next step of the nearest enclosing loop.

More details refer Returns and Jumps,Break and Continue Labels



回答4:

An alternative to the return might be

mainRepo.fetchUpcomingTrips { trips ->
            if (trips.isEmpty())
                showEmptyViews()
            else {
                //run some code if it's not empty
            }
        }


标签: lambda kotlin