Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin 在挂起的函数中调用共同例程生成器(启动,异步)时,coroutineContext不明确_Kotlin_Kotlin Coroutines - Fatal编程技术网

Kotlin 在挂起的函数中调用共同例程生成器(启动,异步)时,coroutineContext不明确

Kotlin 在挂起的函数中调用共同例程生成器(启动,异步)时,coroutineContext不明确,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,我有一个类Runner,它实现了CoroutineScope接口,如下所示。它有一个名为run的挂起函数。当我在这个挂起的运行函数中使用共同例程生成器函数(启动,异步)时,我得到以下警告 由于挂起的CoroutineScope接收器导致coroutineContext不明确 作用 Runner类实现了一个coroutineContext属性。有人能解释一下警告信息背后的逻辑吗 class Runner: CoroutineScope { override private val cor

我有一个类
Runner
,它实现了
CoroutineScope
接口,如下所示。它有一个名为
run
的挂起函数。当我在这个挂起的
运行
函数中使用共同例程生成器函数(
启动
异步
)时,我得到以下警告

由于挂起的CoroutineScope接收器导致coroutineContext不明确 作用

Runner
类实现了一个coroutineContext属性。有人能解释一下警告信息背后的逻辑吗

class Runner: CoroutineScope {

    override private val coroutineContext = Dispatchers.IO

    suspend fun run()  {
           val job1 = launch { delay(2000); println("launching job1") }
           val job2 = launch { delay(2000); println("launching job2") }
           listOf(job1, job2).forEach { it.join() }
    }

}

尽量避免在协同路由作用域的类或函数中挂起函数 除非它会抛出上述警告

class Runner: CoroutineScope {

            override private val coroutineContext = Dispatchers.IO

            suspend fun run()  {
                   val job1 = launch { delay(2000); println("launching job1") }
                   val job2 = launch { delay(2000); println("launching job2") }
                   listOf(job1, job2).forEach { it.join() }
            }

        }


由于“挂起”修改器的原因,它不明确。您的
run()
函数将从另一个couroutineScope调用。因此,它内部的
launch
构建器可以启动一个协同路由,也可以在现有协同路由中挂起。这就是模糊性。可以通过删除“挂起”修改器来修复它:

class Runner : CoroutineScope {

    override val coroutineContext = Dispatchers.IO

    fun run() = launch {
            val job1 = launch { delay(2000); println("launching job1") }
            val job2 = launch { delay(2000); println("launching job2") }
            listOf(job1, job2).forEach { it.join() }
        }

}

您需要明确声明
run()
使用Runner的coroutineContext,这将消除歧义

suspend fun run() = withContext(coroutineContext) {
    val job1 = launch { delay(2000); println("launching job1") }
    val job2 = launch { delay(2000); println("launching job2") }
    listOf(job1, job2).forEach { it.join() }
}
或者,如果添加参数,则可以使用调用run的上下文,例如

suspend fun run(cc:CoroutineContext = coroutineContext) = withContext(cc) {
    val job1 = launch { delay(2000); println("launching job1") }
    val job2 = launch { delay(2000); println("launching job2") }
    listOf(job1, job2).forEach { it.join() }
}

.join()
是一个挂起函数。请您解释一下为什么要“避免在协同程序作用域的类或函数中挂起函数”。因此有一些不同的答案。我想知道什么是最佳做法?谢谢。。有没有一种方法可以访问挂起函数的当前coroutineContext,而不必显式地将其作为参数传递?实际上,这很有意义。。那么CoroutineScope实现类的公共入口点方法必须是非挂起的正则函数?关于这方面的约定是什么?我认为约定是将作用域创建为属性,而不是类。一般来说,您不应该编写实现
CoroutineScope
的类。
suspend fun run(cc:CoroutineContext = coroutineContext) = withContext(cc) {
    val job1 = launch { delay(2000); println("launching job1") }
    val job2 = launch { delay(2000); println("launching job2") }
    listOf(job1, job2).forEach { it.join() }
}