Home > database >  Why is overloading not working for this case in Kotlin?
Why is overloading not working for this case in Kotlin?

Time:08-26

In Kotlin, why is it not able to pick from these functions based on the return type of the suspend function? Apart from providing different function names, which I really don't want to do, what are the alternatives?

@JvmName("hasPermission1")
suspend fun <T> hasPermission(requiredPermissions: String, block: suspend () -> T): DataFetcherResult<T> {
    println("todo check permissions: $requiredPermissions")
    return failureResult(
        Unauthorized()
    )
}

suspend fun <T> hasPermission(requiredPermissions: String, block: suspend () -> DataFetcherResult<T>): DataFetcherResult<T> {
    return failureResult(
        Unauthorized()
    )
}

CodePudding user response:

That is because the block lambda parameter will be converted into Function class. If you look at the error given by the Android Studio, it said that both function has same JVM signature hasPermission(Ljava/lang/String;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;)

This is your block parameter

Lkotlin/jvm/functions/Function1

You can also check it by showing the kotlin bytecode

Tools -> Kotlin -> Show Kotlin Bytecode

CodePudding user response:

Because they have the same signature.

The description of the first block: () -> T is so similar to the second () -> DataFetcherResult<T>, it can't be distiguished. In short: T can literally be DataFetcherResult and the compiler is confused.

Alternative:

Using inline and reified to read the class type inside and decide accordingly:

suspend inline fun <reified T> hasPermission(requiredPermissions: String, block: suspend () -> T): DataFetcherResult<T> {
    return when(T::class) {
            DataFetcherResult::class -> TODO("DataFetcherResult stuff")
            else -> TODO("Other stuff")
        }
}

More info on what reified means and how to use it: here

  • Related