类型不匹配:推断的类型为List <any?>,但预期为List <nothing>

时间:2019-01-15 05:33:34

标签: generics kotlin

我有一个不变的以下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)
        }
    }
}

1 个答案:

答案 0 :(得分:1)

您有一些我不太了解的内容(可能是一个错误)。目前,拥有currentCall类型的Call<*>和通用add方法并没有什么意义,因为您无法设置providercurrentCall

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

class Main<T> {

然后,您可以安全地从add删除通用参数:

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

最后,您还可以用currentCall类型参数generic代替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相关。