【问题标题】:Understanding one usage of "in" keyword in Kotlin了解 Kotlin 中“in”关键字的一种用法
【发布时间】:2019-02-26 16:31:05
【问题描述】:

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

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

这里,IDE 提示说 for 循环正在迭代的项目的类型是 Shape。这很好。

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

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

【问题讨论】:

  • "Kotlin 提供了一个互补的方差注解:在。它使类型参数逆变:它只能被消费而不能被生产"
  • @TimCastelijns 谢谢,但我想了解其背后的原因。再一次,对我来说,这看起来像是一个安全的操作。或者我在这方面错了,但在这种情况下,我真的需要一个示例来可视化这种用法如何破坏语言的类型安全动态。

标签: generics kotlin covariance


【解决方案1】:

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

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

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

在每种情况下,如果您正在使用该列表,那么您从列表中提取的任何内容都将始终是 Shape(正如 IDE 所确认的那样)。

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

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

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

【讨论】:

  • “你的第二个函数,带有一个 MutableList 参数,是相反的:它可以接受一个 Shapes 列表,或者一个 Shape 的任何超类的列表” - 阅读了你的帖子,我完全一样的想法。因此,您可以通过该参数传递 Any 列表,或者 Foo 列表(假设 Shape 扩展了 Foo 类)。它们都不代表会破坏类型安全的 Shape 对象。
猜你喜欢
  • 2013-11-06
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
  • 1970-01-01
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
相关资源
最近更新 更多