我读的是KEEPCoroutine proposal.我在Coroutine Builders区偶然发现了这段代码.

fun launch(context: CoroutineContext = EmptyCoroutineContext, block: suspend () -> Unit) =
    block.startCoroutine(Continuation(context) { result ->
        result.onFailure { exception ->
            val currentThread = Thread.currentThread()
            currentThread.uncaughtExceptionHandler.uncaughtException(currentThread, exception)
        }
    })

并且startCoroutine是函数类型(suspend () -> T)的扩展函数

**
 * Starts a coroutine without a receiver and with result type [T].
 * This function creates and starts a new, fresh instance of suspendable computation every time it is invoked.
 * The [completion] continuation is invoked when the coroutine completes with a result or an exception.
 */
@SinceKotlin("1.3")
@Suppress("UNCHECKED_CAST")
public fun <T> (suspend () -> T).startCoroutine(
    completion: Continuation<T>
) {
    createCoroutineUnintercepted(completion).intercepted().resume(Unit)
}

我想知道startCoroutine()函数如何执行它正在扩展的函数block.因为我在代码中看不到任何this().

createCoroutineUnintercepted()还扩展了相同的函数类型,但那里没有源代码实现.

@SinceKotlin("1.3")
public expect fun <T> (suspend () -> T).createCoroutineUnintercepted(
    completion: Continuation<T>
): Continuation<Unit>

询问ChatGPT没有带来任何答案.它说

当您调用block.startCoroutine(...)时,您实际上是在启动块的执行.

try 实现一个简单的函数类型扩展example,但似乎不起作用.

有谁能告诉我这个扩展函数类型是如何工作的吗?

编译器在挂起这方面的函数时也会施展什么魔力吗?

推荐答案

我想知道startCoroutine()函数如何执行它正在扩展的函数BLOCK.因为我在这段代码中没有看到任何this().

请记住,this在整个函数体的上下文中都是隐式的,因此对this类型的函数或属性(包括扩展)的任何调用都可以在不指定this.的情况下完成.因此,在实践中,startCoroutine()的实现就好像this.是这样写的:

public fun <T> (suspend () -> T).startCoroutine(
    completion: Continuation<T>
) {
    this.createCoroutineUnintercepted(completion).intercepted().resume(Unit)
}

因此,正如您所看到的,(suspend () -> T)接收器被简单地传递到createCoroutineUnintercepted(因为如您所述,它确实具有相同的接收器类型).现在,当然,这只是将问题推到另一个函数上.

但那里没有源代码实现.

事实上,createCoroutineUninterceptedsuspendCoroutineUninterceptedOrReturn都是由Kotlin编译器(称为intrinsics)识别和转换的特殊函数.这就是他们跻身百强的原因.它们是该语言提供的基本构建块,以便构建更用户友好的框架(如Kotlinx Coroutines库).

我推荐这篇博客文章来了解基本的语言原语是什么,以及我们如何从它们构建像Kotlinx Coroutines这样的框架: https://blog.kotlin-academy.com/kotlin-coroutines-animated-part-1-coroutine-hello-world-51797d8b9cd4

除了协程的保留之外,您可能还会发现这个详细的技术文档也很有用: https://github.com/JetBrains/kotlin/blob/master/compiler/backend/src/org/jetbrains/kotlin/codegen/coroutines/coroutines-codegen.md

try 实现一个简单的函数类型扩展示例,但似乎不起作用.

关于这一点,您简单地打印了this(使用$this模板语法),但没有打印call.您可以在代码中添加圆括号以使其正常工作(为此,您需要在字符串模板中添加大括号).因此,只需将$this替换为${this()},它实际上会将其命名并打印您所期望的内容:

inline fun (() -> Int).start() {
    println("start received ${this()}")
}

fun launch(block: () -> Int) {
    block.start()
}

fun main() {
    launch {
        1
    }
}

Kotlin相关问答推荐

在KMM合成多平台中创建特定于平台的视图

Kotlin:类型不匹配:推断的类型已运行,但应等待

Kotlin - 如何避免在密封类的 when() 语句中转换第二个变量

为什么 Kotlin 在将协变类型参数转换为不变类型参数时会产生 Unchecked Cast 警告?

协程子作业(job)取消

使用 StateFlow 时如何移除监听器?

可组合项在返回后返回时组合导航句柄

将 Integer 转换为 Unit 编译成功

如何在 Kotlin 中声明一个空数组而不期望 null?

在 Compose 中使用 Text() 时如何获取文本的大小?

Kotlin 条件格式字符串

正则表达式 FindAll 不打印结果 Kotlin

为什么没有remember 的 mutableStateOf 有时会起作用?

这是什么 Kotlin 类型:(String..String?)

Kotlin 无法找到或加载主类

Anko 中的水平线性布局

Kotlin 中的部分类委托

TextField maxLength - Android Jetpack Compose

Kotlin的BiMap/2-way hashmap

为什么 Kotlin 会收到这样的 UndeclaredThrowableException 而不是 ParseException?