'Overload resolution ambiguity' 在函数中使用和不使用 'suspend' lambda

'Overload resolution ambiguity' with and without 'suspend' lambda in functions

看这个例子:

fun f(block: suspend () -> Unit) {
    println("with suspend")
}

fun f(block: () -> Unit) {
    println("without suspend")
}

fun main() {
    f(suspend {
    })

    // This call cause compilation error:
    // Error:(16, 5) Kotlin: Overload resolution ambiguity:
    // public fun f(block: () -> Unit): Unit defined in root package in file Main.kt
    // public fun f(block: suspend () -> Unit): Unit defined in root package in file Main.kt
    //
    // f({
    // })

    // This call cause compilation error:
    //
    // Error:(25, 5) Kotlin: Overload resolution ambiguity:
    // public fun f(block: () -> Unit): Unit defined in root package in file Main.kt
    // public fun f(block: suspend () -> Unit): Unit defined in root package in file Main.kt
    //
    // f {
    // }
}

这里声明了两个函数(一个在 lambda 中带有 suspend 关键字,一个没有)。

问题:

1) 如何调用第一个或第二个函数?如您所见,我可以使用 suspend 调用函数,但不能在没有 suspend 关键字的情况下调用函数。

2) 可以用 trailing lambda 重写 f(suspend {})(即使用类似 f suspend {} 的东西)?

1) 您可以通过一些变通方法调用第二个函数。例如,

val foo = {}
f(foo)

f({}.also{})

甚至更短:

f({}!!)

将调用带有非挂起参数的函数。在这些情况下,您在作为函数参数的上下文之外声明 lambda,因此默认情况下它不可暂停。

2) 尾随 lambda 语法不支持显式 suspend 修饰符,因此您必须使用括号来声明您的 lambda 是可暂停的。