Koltin Generics声明 - 场地差异<in t =“”>构造

时间:2017-08-03 19:15:22

标签: java generics kotlin

我正在阅读kotlin没有通配符的原因(https://kotlinlang.org/docs/reference/generics.htm l)。这一切都来自声明网站的差异。我们有<in T><out T>构造,应该替换通配符。我想我理解<out T>是如何运作的,但我对<in T>有麻烦。
所以在java中我们可以写这样的东西:

public List<? extends Number> list1;
public List<? super String> list2;

初始化后的第一种情况变为只读列表(虽然不完全不可变,因为我们可以清除它),如果我们将每个元素都视为数字,则可以读取。 第二种情况是只写(虽然我们可以读取它,如果我们将每个元素视为对象)。我们可以写String和它的子类。
在Kotlin中,我能够使用<out T>重新创建list1示例,如下所示:

class Service {
  val container = Container(mutableListOf("1", "2", "3"))
}
class Container<T>(var list1: MutableList<out T>)

最后,我尝试了与<in T>同心的事情,认为我可以重新创建list2示例,但是我失败了:  enter image description here

有人可以向我解释如何在Kotlin中实现我的list2示例吗?我该如何以正确的方式使用<in T>构造?

1 个答案:

答案 0 :(得分:4)

Kotlin List<E>不等同于Java List<E>。 Java列表具有变异功能,而Kotlin列表是只读的。它是Kotlin MutableList<E>,相当于Java列表。

接下来,看一下List<E> declaration:它的类型参数是covariant(out E),并且使用站点方差不能覆盖声明站点差异,这就是为什么你不能拥有List<in T>

此外,声明网站差异out E表示E永远不会出现在in - 位置(没有E类型的函数参数,也没有E的可变属性类型List<E>),实际上,由于E是只读的,因此class Container2<T>(var list2: MutableList<in T>) 不会将MutableList<E>带入任何函数(*)

您可以将示例转换为使用MutableList<E>代替:

E

in界面有<in T>不变量,<out T> - 使用网站上的投影与声明网站差异不冲突。

(*)实际上,it does,但只使用标有@UnsafeVariance注释的参数,这些参数只是抑制方差冲突,可以找到更多关于它的{{3} }。

另外,一句小话:

  

这一切都来自声明网站的差异。我们有List<CharSequence>List<out CharSequence>构造,应该替换通配符。

实际上是使用站点方差取代了Java通配符。声明 - 站点方差仅应用于类型参数声明(定义类型的位置),并且当它是时,该类型的所有用法都将具有该方差(例如,当您使用List<out E>时,它实际上是{ {1}}因为y_train的声明 - 网站差异。因此,使用站点方差适用于泛型类型的特定用法。