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

时间:2019-06-26 10:30:15

标签: android kotlin

我正在使用密封类从网络返回数据。但是当我构建项目时,出现以下错误

  

类型推断失败:没有足够的信息来有趣地推断参数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 个答案:

答案 0 :(得分:2)

State.error( e.message ?: "Unknown Error", e )这行中,编译器不知道T应该是什么。如果将其与success进行比较,则会看到您显式提供了T的参数,编译器使用该参数来推断类型。 您可以在调用错误时像这样指定它:

State.error<TYPE_OF_SCHEDULE_REMINDER_LIST>( e.message ?: "Unknown Error",  e  )

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

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)
    }
}

答案 1 :(得分:1)

Error数据类定义了T类型的参数,但未以任何方式使用它。因此,在创建Error实例时,编译器无法推断T应该使用哪种类型。

要解决此问题,请更改StateError的定义,以使它们没有类型参数。

答案 2 :(得分:0)

@s1m0nw1 answer相对,如果要将类型参数保留在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)
    }
}

那样,您的示例方法将保持不变,并且无需执行不安全的强制转换