1

I wanted to understand what is actual use case when we would want to add crossinline keyword to a lambda

I have following code where I added crossinline. I understand that crossinline will force any of the calling method to force it to local-return only.

fun main() {
print("Main Call")
higherOrderFunction {
    print("Step inside lambda")
    return@higherOrderFunction
}
print("Main Call After")
}

inline fun higherOrderFunction(crossinline lambda: () -> Unit) {
print("Inside Higher Order")
lambda()
}

What I don't understand is the actual use case of using it. When does it becomes absolutely necessary to use crossinline? What's the advantage of enforcing the non-local return. What is that use case when we can't rely on developer to manually local-return. Asking this because if I remove the crossinline in the same code, it works fine even then. I checked the decompiled code and I see that its same for both the code.

fun main() {
print("Main Call")
higherOrderFunction {
    print("Step inside lambda")
    return@higherOrderFunction
}
print("Main Call After")
}

inline fun higherOrderFunction(lambda: () -> Unit) {
print("Inside Higher Order")
lambda()
}
Hack123
  • 95
  • 7

1 Answers1

4

Suppose you want to call this lambda outside the context of your inline function, such as calling it inside the lambda of another function you are calling:

inline fun doOnOkButtonClick(crossinline lambda: () -> Unit) {
    okButton.setOnClickListener {
        Log.i(TAG, "Executing OK button action") 
        lambda()
    }
}

In this situation, it is necessary to prohibit non-local returns in that lambda, because the lambda is getting called outside the context of the inlined code. That OK button listener can't return from the function that called doOnOkButtonClick since the OK button is getting clicked some time later. There would be no logical path for the code execution to follow when it reached the code that instructs it to return from the caller of doOnOkButtonClick or to break out of a loop in that caller, etc.

The same situation will also occur if you want to assign that lambda to some property or pass it to a different higher-order function that is not inlined or has a cross-inline parameter.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154