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