When lambda parameters must be noinline in Kotlin?
Answer #1 100 %It's less of "disqualifying" the lambda from being inlined and more of "this action can't be performed on an inlined lambda."
I kind of answered this here.
Inlined methods are directly inserted into the call site, as are any inlined lambdas.
To reuse my old example,
this roughly results in main
here:
fun withLambda(lambda: () -> Unit) {
lambda()
}
inline fun inlinedLambda(lambda: () -> Unit) {
lambda()
}
fun main(args: Array) {
withLambda { println("Hello, world") }
inlinedLambda { println("Hello, world") }
}
being converted to this:
fun main(args: Array) {
withLambda { println("Hello, world") }
println("Hello, world") // <- Directly inserted!
}
What you cannot do with an inlined lambda is treat it like an object.
This means you cannot store it in a field:
val a = lambda // <-- error
or call methods on it:
lambda.toString() // <-- error
because it is not an object.
It can also not be passed as an argument to another function
func(lambda) // <-- error
unless the lambda is marked as crossinline
, and the other function's parameter is inline
.
This is basically stated by the documentation.
noinline ones can be manipulated in any way we like: stored in fields, passed around etc.
Note that some inline functions may call the lambdas passed to them as parameters ... To indicate that, the lambda parameter needs to be marked with the crossinline modifier:
Think of inlined lambdas as having their code directly inserted into the method. Conceptually they do not actually exist, and "calling" them will just insert their contents into the calling method.