类型推断失败:没有足够的信息来推断参数T Kotlin。

3

我正在使用一个密封类从网络返回数据。但是在构建项目时,我遇到了以下错误:

类型推断失败:在fun error(errorMessage: String, error: Throwable): State中无法推断出参数T的足够信息,请明确指定。

我漏掉了什么?

以下是代码:

suspend fun getdataFromApi(context: Context?, token: String?): State<ScheduleReminderListResponse> =
    withContext(schedulerProvider.io)
    {

            try {
                val list = network.getScheduleReminderList(token).await()
                schedeleReminderListLocalDao.insertAll(list)
                return@withContext State.success(list)
            } catch (e: Exception) {
                return@withContext State.error( e.message ?: "Unknown Error",  e  )
            }


        }






sealed class State<T> {

class Loading<T>: State<T>()
data class Error<T>(val errorMessage: String?, val error: Throwable): State<T>()
data class Success<T>(var data: T) : State<T>()

companion object {
    fun <T> loading(): State<T> =
        Loading()

    fun <T> error(errorMessage: String, error: Throwable): State<T> =
        Error(errorMessage, error)

    fun <T> success(data: T): State<T> =
        Success(data)

   }
 }
3个回答

6
在这行代码中 State.error( e.message ?: "Unknown Error", e ),编译器并不知道应该是哪个 T。如果你将其与 success 进行比较,你会发现你需要显式地提供一个 T 参数给编译器去推断类型。 在调用 error 方法时,你可以这样指定它:
State.error<TYPE_OF_SCHEDULE_REMINDER_LIST>( e.message ?: "Unknown Error",  e  )

由于您在Error中没有使用T,因此您可能需要考虑从封闭类中完全删除它,并仅在有意义的地方使用它。

sealed class State {

    object Loading : State()
    data class Error(val errorMessage: String?, val error: Throwable) : State()
    data class Success<T>(var data: T) : State()

    companion object {
        fun loading(): State = Loading

        fun error(errorMessage: String, error: Throwable): Error =
            Error(errorMessage, error)

        fun <T> success(data: T): Success<T> = Success(data)
    }
}

2

Error数据类定义了T类型参数,但在任何方面都没有使用它。因此,当你创建一个Error实例时,编译器无法推断该使用哪种类型作为T。

要解决这个问题,修改StateError的定义,使它们不再具有类型参数。


1
@s1m0nw1的答案相反,如果您想在State模型中保留类型参数(以便返回值看起来更美观且类型安全),您可以考虑将T标记为out并在不使用它的子类中使用Nothing
sealed class State<out T> {

    object Loading: State<Nothing>()
    data class Error(val errorMessage: String?, val error: Throwable): State<Nothing>()
    data class Success<T>(var data: T): State<T>()

    companion object {
        fun <T> loading(): State<T> = Loading

        fun <T> error(errorMessage: String, error: Throwable): State<T> = Error(errorMessage, error)

        fun <T> success(data: T): State<T> = Success(data)
    }
}

那样你的示例方法将保持不变,您无需执行不安全的转换。

作为额外的好处,您可以尝试跳过伴生对象并直接使用构造函数。 - V-master

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接