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.crossinline
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
)inline
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 bodycrossinline
)The 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.inline 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