Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Look at this example:

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 {
    // }
}

Here is declared two functions (one with suspend keyword in lambda and one without).

Questions:

1) How to call first or second function? As you can see I can call function with suspend but can't call function without suspend keyword.

2) It is possible to rewrite f(suspend {}) with trailing lambda (i.e. use something like f suspend {})?

like image 297
Maxim Avatar asked Feb 16 '20 10:02

Maxim


1 Answers

1) You can call the second function with some workarounds. For example,

val foo = {}
f(foo)

or

f({}.also{})

or even shorter:

f({}!!)

will invoke the function with non-suspend parameter. In these cases you declare the lambda out of the context of being a function parameter, so it's not suspendable by default.

2) Trailing lambda syntax does not support explicit suspend modifier, so you have to use parentheses to declare that your lambda is suspendable.

like image 62
ardenit Avatar answered Oct 17 '22 01:10

ardenit