gpt4 book ai didi

列表回调参数上的 Kotlin 通配符捕获

转载 作者:行者123 更新时间:2023-12-01 08:26:22 26 4
gpt4 key购买 nike

java :

public class JavaClass implements ModelController.Callback {

@Override
public void onModelsLoaded(@NonNull List<? extends Model> models) {
doSomething(models);
}

private void doSomething(List<Model> models) { }

}

Kotlin :
class ModelController {
var callback = WeakReference<Callback>(null)

interface Callback {
fun onModelsLoaded(models: List<Model>)
}

fun someFunction() {
callback.get().onModelsLoaded(ArrayList<Model>())
}
}

interface Model {

}

没有 ?在 Java onModelsLoaded 方法中扩展了 Model,覆盖与 Kotlin 中的接口(interface)不匹配。有了它,我收到以下错误:
doSomething(<java.util.List<com.yada.Model>) cannot be applied to (java.util.List<capture<? extends com.yada.Model>>)

为什么需要通配符捕获,为什么不允许将其用于非通配符方法?

最佳答案

问题源于 Kotlin 集合为 variant ,而 Java 仅具有通过通配符实现的使用站点差异(捕获与通配符相关,但不完全是 ? extends ... 语法本身)。

当我们在 Kotlin 中说 List<Model> 时,它的意思是“Model 的只读列表或 Model 的子类型”,当我们在 Java 中说同样的话时,它的意思是“正好是 Model 的可变列表,仅此而已”。大致意思是 Kotlin 的 List<Model> 意味着什么,在 Java 中我们必须说 List<? extends Model> ,这就是为什么要让覆盖工作你必须在 Java 代码中添加通配符。

现在,您的 doSomething 是用 Java 编写的,并说它想要“正好是 Model 的列表”,当您给它“Model 或其子类型的列表”时,Java 编译器会提示,因为它可能很危险:doSomething 可能尝试做一些对于 ModelImpl 列表不合法的事情,因为它认为它正在处理 Model 列表。

截至目前(Kotlin Beat 2),您有两种选择:

  • 在您的 Kotlin 代码中使用 MutableList<Model> - 这正是 Java 的 List<Model>
  • 的含义
  • 定义 doSomething 以便它采用 List<? extends Model> ,这就是您当前的 Kotlin 代码的含义。

  • 在 Kotlin 的下一次更新中,我们将在类型上添加一个注释,以便为这个问题提供更简洁的解决方法。

    关于列表回调参数上的 Kotlin 通配符捕获,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33877225/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com