问题
I'm looking into launch
coroutine builder which takes coroutine code as block: suspend CoroutineScope.() -> Unit
. We usually pass the code as lambda. However, I was wondering how to pass this function as explicit parameter to launch function.
coroutineScope {
launch(block = ::myFunction)
}
suspend fun CoroutineScope.myFunction(): Unit {
// coroutine code
}
It gives following error
Type mismatch.
Required:
suspend CoroutineScope.() → Unit
Found:
KSuspendFunction0<Unit>
What is it that i'm missing?
回答1:
The syntax for extension function references is the same as for member functions:
launch(block = CoroutineScope::myFunction)
回答2:
How about this way?
coroutineScope {
launch(block = myFunction())
}
fun myFunction(): suspend CoroutineScope.() -> Unit = {
for(i in 3 downTo 1) {
println("$i")
delay(1000)
}
}
回答3:
According to kotlin doc, launch function with parameter is function type: CoroutineScope.() → Unit, is one function type with receiver.
Function types with receiver, such as A.(B) -> C, can be instantiated with a special form of function literals – function literals with receiver.
The same article also noted the following:
Using a callable reference to an existing declaration:
a top-level, local, member, or extension function: ::isOdd, String::toInt,
a top-level, member, or extension property: List<Int>::size,
a constructor: ::Regex
These include bound callable references that point to a member of a particular instance: foo::toString.
but not adaptive to "function literals with receiver".
so one way to make it work:
coroutineScope {
launch {
myFunction()
}
}
来源:https://stackoverflow.com/questions/61037236/how-to-pass-suspend-function-as-explicit-parameter-to-coroutine-builder