how to pass suspend function as explicit parameter to coroutine builder?

强颜欢笑 提交于 2020-07-20 14:42:20

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!