首页 > 解决方案 > 类型不匹配:推断类型为 List但是列表预计

问题描述

我有以下Call不变的接口,在另一个类中我想调用它的一个函数,但是在这一行中出现以下错误currentCall?.refresh(result)

Type mismatch: inferred type is List<Any?> but List<Nothing> was expected.
Projected type Call<*>? restricts use of public abstract fun refresh(list: List<T>): Unit defined in 

我知道使用星形投影,类型会变得未知,并且使用它是不安全的。我不知道改变结构并允许此操作的最佳方法是什么。

在这种情况下你会怎么做?例如,您将如何刷新数据?

interface Call<T> {
    fun provider(): Provider<T>
    fun items(): List<T>
    fun refresh(list: List<T>)
}

interface Provider<T> {
    fun enqueue(result: (List<T>) -> Unit)
}

class Main {

    private var currentCall: Call<*>? = null

    fun <T> add(provider: Provider<T>){}

    fun onStart() {
        currentCall?.provider()?.enqueue { result ->
            currentCall?.refresh(result)
        }
    }
}

标签: genericskotlin

解决方案


你有一些我不太明白的东西(这可能是一个错误)。currentCall目前,您拥有类型Call<*>和泛型方法并没有真正意义,add因为您绝不可能设置provider.currentCall

Main当您也制作通用时,可以解决此问题:

class Main<T> {

然后,您可以安全地从以下位置删除泛型参数add

fun add(provider: Provider<T>){}

currentCall最后,您也可以使用generictype 参数替换 的星形投影T

private var currentCall: Call<T>? = null

这给你留下了一个像这样的课程:

class Main<T> {

    private var currentCall: Call<T>? = null

    fun add(provider: Provider<T>){}

    fun onStart() {
        currentCall?.provider()?.enqueue { result ->
            currentCall?.refresh(result)
        }
    }
}

这是可行的,因为您明确告诉编译器您使用的每种类型都Main 必须T.


推荐阅读