https://kotlinlang.org logo
Title
a

Alexander Finn

04/22/2020, 4:29 PM
I have a newbie generics question here. I'm using a library (KMongo) that exposes an inline method with reified parameter:
inline fun <reified TDocument : Any> getCollection(
    collectionName: String = KMongoUtil.defaultCollectionName(TDocument::class)
): CoroutineCollection<TDocument>
In my code I want to create an interface with a default method that would return a collection for specified type:
interface MongoDBRepository<T: Any> {

    val client: CoroutineClient

    fun collection(): CoroutineCollection<T> {
        return client.getDatabase(accountId).getCollection<T>()
    }

}
However, the compiler complains that 'T' can not be used as a reified type parameter here. And defining a reified type parameter would require me to change collection() to an inline function which is something I can not do in an interface. Any thoughts on how to change the code to make an interface functional? Or am I doing something completely wrong?
g

giylmi

04/22/2020, 5:47 PM
If you do not need to override the method, you can rewrite the function as inline extension function with reified type parameter
d

Dennis Schröder

04/23/2020, 7:41 AM
Classes or Interfaces can not have a reified type parameter
g

giylmi

04/23/2020, 7:42 AM
This works perfectly. But as I said, you won't be able to override it
import io.ktor.client.HttpClient
import <http://io.ktor.client.request.post|io.ktor.client.request.post>

interface BaseApi {
    val client: HttpClient
}

suspend inline fun <Request: Any, reified Response: Any> <http://BaseApi.post|BaseApi.post>(url: String, request: Request? = null): Response {
    return <http://client.post|client.post>(url) {
        request?.let {
            body = it
        }
    }
}