关于 runSuspend 的问题

来源:12-2 案例:仿官方框架实现 launch 2

xxxxjase普通

2020-10-16

我把 RunSuspend.kt 的内容拷贝到我自己的文件中:

@SinceKotlin("1.3")
internal fun runSuspend(block: suspend () -> Unit) {
    val run = RunSuspend()
    block.startCoroutine(run)
    run.await()
}

private class RunSuspend : Continuation<Unit> {
    override val context: CoroutineContext
        get() = EmptyCoroutineContext

    var result: Result<Unit>? = null

    override fun resumeWith(result: Result<Unit>) = synchronized(this) {
        this.result = result
        @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
    }

    fun await() = synchronized(this) {
        while (true) {
            when (val result = this.result) {
                null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
                else -> {
                    result.getOrThrow() // throw up failure
                    return
                }
            }
        }
    }
}

然后反编译:

public final class RunSuspend1Kt {
   @SinceKotlin(
      version = "1.3"
   )
   public static final void runSuspend(@NotNull Function1 block) {
      Intrinsics.checkParameterIsNotNull(block, "block");
      RunSuspend run = new RunSuspend();
      ContinuationKt.startCoroutine(block, (Continuation)run);
      run.await();
   }
}

发现 runSuspend 的参数变成了一个 Function1 实例了;

但是在 kotlin 里面是一个 block: suspend () -> Unit

我在跟踪 suspend main 的时候也发现这个问题了,这是为什么呢?为啥不是一个 Continuation 呢???

写回答

2回答

bennyhuo

2020-10-16

这题我讲过的哈,suspend 函数本质上的类型是在参数列表里面加了一个 Continuation

suspend () -> Unit 的类型实际上是 (Continuation) -> Unit

1
6
bennyhuo
回复
xxxxjase普通
startCoroutine的时候,会用这个lambda创建一个SuspendLamba 的子类,然后在resume的时候调用这个Lambda,这样理解吧。我看现在的源码也差不多是这个意思了。
2020-10-18
共6条回复

xxxxjase普通

提问者

2020-10-16

老师记得回复哦

0
0

学会Kotlin 突破开发语言瓶颈

如果有一门语言可以取代Java,那么它一定是Kotlin。

1760 学习 · 481 问题

查看课程