Koltin泛型声明 – 站点方差<T>构造
我正在阅读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;
初始化后的第一种情况变成只读列表(虽然不是完全不可改变的原因,我们可以清除它),如果我们把每个元素都视为数字,就可以读取它们。
第二种情况是只写(尽管我们可以阅读它,如果我们把每个元素作为对象)。 我们可以写那里字符串和它的子类。
在Kotlin中,我能够像这样使用<out T>
重新创建list1示例:
class Service { val container = Container(mutableListOf("1", "2", "3")) } class Container<T>(var list1: MutableList<out T>)
最后我尝试了一些类似于<in T>
东西,认为我可以重新创建list2的例子,但是我失败了:
有人可以向我解释如何在Kotlin中实现我的list2例子吗? 我应该如何正确使用<in T>
结构?
Kotlin List<E>
不等于Java List<E>
。 Java列表具有变异功能,而Kotlin列表是只读的。 它是Kotlin MutableList<E>
,等同于Java列表。
接下来,看一下List<E>
声明 :它的类型参数是协变的( out E
),并且声明站点的变量不能被使用站点变量覆盖,这就是为什么你不能在List<in T>
有一个List<in T>
。
此外,声明站点方差out E
意味着E
永远不会出现在一个in
-position(没有E
类型的函数参数,也不是E
类型的可变属性),事实上,由于List<E>
是只读的,不会将E
带入其任何功能(*) 。
你可以转换你的例子来使用MutableList<E>
来代替:
class Container2<T>(var list2: MutableList<in T>)
MutableList<E>
接口具有E
不变性,而use-site中的MutableList<E>
不与声明网站方差冲突。
(*)实际上, 它只是使用标有@UnsafeVariance
注解的参数,它简单地抑制了方差冲突,更多关于它的信息可以在这里找到。
另外,一个小的评论:
这一切都来到声明网站的变化。 我们有
<in T>
和<out T>
结构应该取代通配符。
这实际上是用于替换Java通配符的使用站点差异。 声明站点的差异只适用于类型参数声明(类型被定义的地方),当它是时,类型的所有用法都会有差异(例如当你使用List<CharSequence>
,它实际上是一个List<out CharSequence>
因为List<out E>
的声明站点变化)。 因此,使用地点差异对于通用类型的特定用途而言。