yaugenka
yaugenka

Reputation: 2861

Kotlin class generic type infered as nullable

A generic class for holding network request result

sealed class Result<out T : Any?> {
    data class Success<out T : Any?>(val data: T) : Result<T>()
    data class Error(val message: String, val exception: Exception? = null) : Result<Nothing>()
}

A generic function for encapsulating network result into Result. It is called from a repository and passes a retrofit2 api call as an input parameter

suspend fun <T: Any?> request(method: Call<T>): Result<T> {
    return withContext(Dispatchers.IO) {
        try {
            val response = method.awaitResponse()   // Retrofit2 Call
            if (response.isSuccessful)
                Result.Success(response.body())
            else
                response.getErrorResult()
        } catch (e: Exception) {
            Result.Error(e.message.orEmpty(), e)
        }
    }
    // Type mismatch.
    // Required: Result<T>
    // Found: Result<T?>
}

It is called like this

interface Webservice {
    @GET("data")
    fun getData(): Call<Data>   // Retrofit2
}

suspend fun getData(): Result<Data> {
    return request(webservice.getData())
}

Why does it infer the result as type T? but not T?

Upvotes: 1

Views: 207

Answers (1)

Sweeper
Sweeper

Reputation: 271420

The problem is this line:

Result.Success(response.body())

body is marked with Nullable, so when ported to Kotlin, response.body() returns a T?, rather than T. See here for how this works.

Therefore, the type parameter for Result.Success is inferred to be T?, and so the expression above creates a Result<T?>. Note that the T in Result<T?> refers to the type parameter of request.

Upvotes: 1

Related Questions