了解 Kotlin 中“in”关键字的一种用法

std*_*out 0 generics covariance kotlin

我试图理解 Kotlin 对泛型的理解,尤其是使用inandout关键字。我写了这篇简单的文章,希望能说明我的困惑点。

这是看起来和工作正常的方法;

在此处输入图片说明

在这里,IDE 给出了一个提示,说 for 循环迭代的项目的类型是 a Shape。这很好。

上述方法的另一个版本乍一看似乎不太正确(因为它是“消费者”)。但我想要做的就是阅读一个形状列表,这就是这个from.

在此处输入图片说明

这不起作用,根据规则可能是正确的,但我无法在这里连接点。这似乎是一个安全的操作。我还可以看到 Kotlin 将类型简化为“Any?” 这解释了为什么这已经给出了编译器错误。有人可以在这里解释一下潜在的类型不安全吗?

gid*_*dds 5

方差始终是一个难以解决的概念……

如果您使用术语“生产者”和“消费者”,请注意它们指的是您与相关项目的交互,在本例中为MutableList参数。

您的第一个带有MutableList<out Shape>参数的函数可以接受Shapes 的列表或 的任何子类的列表Shape。(out大致意思是“或任何子类”。)

在每种情况下,如果您正在使用列表,无论您从列表中取出什么,都将始终是 a Shape(正如 IDE 所确认的那样)。

但是,如果您想将某些内容放入列表中(作为生产者),您无法确定添加哪些内容是安全的,因为这取决于它是否是子类以及是哪个子类。

带有MutableList<in Shape>参数的第二个函数正好相反:它可以接受Shapes 的列表,或.的任何超类的列表Shape。(in大致意思是“或任何超类”。)

在每种情况下,将 aShape放入列表总是安全的(作为生产者)。但是你不能告诉你它(作为消费者)中取出的东西的类型:它可以用 a 调用MutableList<Any?>,它可以包含Strings 或Files 或其他任何东西。所以编译器会给它通用类型,Any?(正如 IDE 确认的那样)。