【问题标题】:Type mismatch: inferred type is List<Any?> but List<Nothing> was expected类型不匹配:推断类型是 List<Any?> 但 List<Nothing> 是预期的
【发布时间】:2019-01-15 05:33:33
【问题描述】:

我有以下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)
        }
    }
}

【问题讨论】:

    标签: generics kotlin


    【解决方案1】:

    你有一些我不太明白的东西(这可能是一个错误)。目前,拥有Call&lt;*&gt; 类型的currentCall 和通用add 方法并没有真正意义,因为您无法设置currentCallprovider

    当你将Main 设为泛型时,这个问题可以解决:

    class Main<T> {
    

    然后您可以安全地从add 中删除泛型参数:

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

    最后你也可以用generic类型参数T替换currentCall的星形投影:

    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 有点相关。

    【讨论】:

    • 间接我可以设置和使用它。我不能有一个通用的 Main,这会阻止有多个不同类型的提供程序。
    猜你喜欢
    • 2020-03-02
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    相关资源
    最近更新 更多