• 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只会保证写,而不能读,如果读的话肯定就会出问题。

  • 相关阅读:
    每天学点Linux-选取命令CUT和GREP
    每天学点Linux-切割命令split
    基于netty-socketio的web推送服务
    Redis学习-LUA脚本
    spring中InitializingBean接口使用理解
    外包采用Gradle生成多套app打包
    Android Studio 快捷键 for mac
    使用ClipboardUtils兼容API LEVEL 11以下实现复杂粘贴
    finished with non-zero exit 添加v7包报错的问题
    Infer初体验 for Android
  • 原文地址:https://www.cnblogs.com/webor2006/p/11295576.html
Copyright © 2020-2023  润新知