The Monster
09/06/2021, 11:14 PMinline fun test(crossinline callback: () -> Unit){
callback()
}
The doc says:
some inline functions may call the lambdas passed to them as parameters not directly from the function body, but from another execution context, such as a local object or a nested function.
which I understood as:
an inline function is not allowed to call the crossinline parameter directly in its scope, ...
But why does the code snippet works and I was able to call callback() directly? Does the doc meant to say that you can call the crossinline argument directly and within another local scope as well?Joffrey
09/06/2021, 11:17 PMcrossinline modifier allows you to use the argument in other scopes in addition to being able to use it directly. It does so by forbidding non-local returns inside the lambda that is passed on the call site.Joffrey
09/06/2021, 11:18 PMcrossinline is this kind of usage:
fun someOtherFun() {
// calling test() with a non-local return
// that tries to return from someOtherFun
test {
return // compile error due to crossinline
}
}The Monster
09/06/2021, 11:43 PMcrossinline as hybrid then? The crossinline makes the lambda argument hybrid in the sense that it can be used in other scopes (like noinline) inline)The Monster
09/06/2021, 11:45 PMinline can have returnJoffrey
09/06/2021, 11:49 PMnoinline doesn't inline the lambda at all, so you can pass it around, store it in variables, use it in nested scopes etc. but you cannot use non-local returns (because it's not inlined in the call site so it wouldn't make sense).
⢠crossinline is inlined, but because it can be inlined in nested contexts you have to give up non-local returns (so you don't mess up the control flow in the nested functions that will call that lambda)
⢠regular inline: you can use non-local returns on the call site, but on the flip side you cannot nest it in other contexts inside the inline function bodyJoffrey
09/06/2021, 11:51 PMcrossinline)The Monster
09/06/2021, 11:58 PMThe Monster
09/06/2021, 11:58 PMJoffrey
09/07/2021, 12:02 AMnoinline you can assign the lambda argument to a variable, which you cannot do with an inline lambda.Joffrey
09/07/2021, 12:03 AMinline fun test(callback: () -> Unit) {
val x = callback // forbidden
}
inline fun test(noinline callback: () -> Unit) {
val x = callback // allowed
}The Monster
09/07/2021, 12:16 AM