Kotlin使用处协变的意义与用法

在上一次https://www.cnblogs.com/webor2006/p/11294849.html中对于Java的协变和Kotlin的协变提到了它们的区别,回忆一下:

 其实在Kotlin中也有使用处协变(use-site variance),也叫(type projection类型投影),我们知道当一个类的泛型声明为out之后,所有用到该泛型的只能做为返回类型,而实际场景肯定不能完全满足这一点,所以说如果在泛型中还想达到子类的对象赋值给父类型,那么就不能在声明处声明为out了,此时使用式的协变就可以解决此场景,下面先来看一下Kotlin的Array的定义,接下来的例子会使用它:

接下来定义一个方法:

接下来则使用一下,先来构造一个from:

接下来to的生成采用直接构造的方式,先来看一下Array的构造方法:

那怎么构造呢?如下:

其实构造的Lamda表达式有更精简的写法:

其实还有另一种写法,就是说如果每一个元素的值都初始化一样的,那么可以这样写:

好,接下来就来调用copy函数:

下面假设这个赋值是能成立的,那,是不是说我可以这样写:

但是!!!问题来了,如果我们从中取元素时,那就跪了,我不知道它具体是Int还是String还是其它类型,所以这种情况就乱套了,所以应该禁止程序员来对它进行写操作,那么协变的威力就发挥作用了,另外从实际角度来考虑很显然这个赋值预期应该是能被赋值成功的,接下来使用处协变就可以发挥作用啦,也是使用out,如下:

擦!!这不就是声明式的协变么?注意!!!不是哈~~声明式的协变长啥样,回忆一下:

而咱们目前使用的使用处协变是在一个具体类型上使用了out,如下:

这样就代表:

如果写的话就会报错:

这也是协变的意义所在,接下来再来看一下使用处逆变的例子:

接下来继续修改,引出逆变:

所以,使用处逆变修改为:

其能成功的原因其实跟上节分析的逆变是一样的,最终原因还得归功于多态,如下:

因为in只会保证写,而不能读,如果读的话肯定就会出问题。

原文地址:https://www.cnblogs.com/webor2006/p/11295576.html