【问题标题】:Kotlin: tailrec makes suspend fun never endsKotlin:tailrec 让暂停的乐趣永无止境
【发布时间】:2020-06-24 03:13:22
【问题描述】:

我正在学习如何使用 CompletableFuture 使协程与 Java 库一起工作。以下是我的代码:

// x invokes y invokes z invokes Java client
suspend fun x(i: Int, client: FakeJavaClient): Int {

    fun z(k: Int): Int {
        println("z: $k")
        return client.query(k).get()
    }

    tailrec // with 'tailrec', the code never terminates
    suspend fun y(j: Int): Int {
        val ret = z(j)
        if (ret > 10) {
            return ret
        }

        return y(j + 1)
    }

    return y(i)
}

fun main()  {
    runBlocking {
        launch(Dispatchers.IO) {
            FakeJavaClient().use { x(0, it) }
        }
    }
    println("Done")
}

class FakeJavaClient : AutoCloseable {
    private val executor = Executors.newFixedThreadPool(10)

    fun query(i: Int): CompletableFuture<Int> {
        val f = CompletableFuture<Int>()
        executor.submit {
            Thread.sleep(1000)
            f.complete(i * 2)
        }
        return f
    }

    override fun close() {
        executor.shutdown()
        executor.awaitTermination(10, TimeUnit.SECONDS)
    }
}

如果我将tailrec 修饰符添加到函数y,代码输出如下所示并且永不结束:

z: 0
z: 0
z: 0
z: 0
z: 0
...

如果我删除 y 上的 tailrec,代码将按照我的预期运行

z: 0
z: 1
z: 2
z: 3
z: 4
z: 5
z: 6
Done

有人可以帮我理解这里发生了什么吗?

【问题讨论】:

    标签: kotlin coroutine kotlin-coroutines


    【解决方案1】:

    这似乎是一个已知问题:Wrong code generated for a local tailrec suspend function

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-14
      • 2020-04-05
      • 2022-07-25
      • 2021-12-30
      • 2019-11-22
      相关资源
      最近更新 更多