zoukankan      html  css  js  c++  java
  • Kotlin星投影与泛型约束详解

    星投影(star projection):

    继续来学习Kotlin泛型相关的东东,星投影(star projection),这是个啥东东呢?下面先来说一下概念:

    1、对于Star<out T>协变:如果T的上界是TUpper,那么Star<*>就相当于Star<out T>,这表示当T的类型未知时,你可以安全地读取TUpper类型的值,言外之意就是从Star<*>取出来的元素都会当成TUpper类型。

    2、对于Star<in T>逆变:Star<*>就相当于Star<in Nothing>,其中Nothing的类定义为:

    这就表示你无法向其中写入任何值。

    3、对于Star<T>不变:如果T的上界为TUpper,那么Star<*>就相当于读取时的Star<out TUpper>以及写入时的Star<in Nothing>。

    了解了概念之后,下面来看具体的实例,先来看第一条:

    接着再来看第二条:

    接下来看代码:

    这段代码能编译通过么?打开注释就知道了:

    其实原因就是如前面第二条理论所说:

    接下来再定义第三点的实例:

    其能正常读取的原因是根据第三点的理论:

    但是不能写入,因为:

    试试:

    果真如此,接下来再来举个例子:

    好,接下来改一下:

    其实就是第三点所说,我们看一下MutableList的泛型定义就知道了:

    泛型约束: 

    再来看一下关于协变跟逆变相关的东东:

    而如果这样:

    但是!!在某些实际情况下可能不得已要能将它作为参数进行写入,那怎么打破这个规则呢?其实Kotlin给咱们提供了一个注解能打破此规则,如下:

    咱们看一下该注解的解释:

    也就意味着,通过该注解告诉使用者这样使用是有安全隐患的,后果自负,下面来使用一下它:

    接下来再继续:

    myStorage2是指向Int类型的myStorage1,而居然往myStorage2中写入了一个字符串,这不是违背常理么?其实原因是泛型擦除所决定的,我们在代码中声明的任何类型类型其实到了字节码当中都会不成Object类型,也就是泛型在字节码的层面类型信息就被擦除了,而当我们从泛型来读取时则会强制进行类型转换,回到咱们的程序,当在执行myStorage2.getValue()时,其实最终会强制转换成Any类型,所以程序也没毛病。

    泛型函数:

    这个在Java中也存在,下面直接看下代码:

    下面来使用一下:

    其实还可以类型推断简化一下:

    对于泛型,如果想约束只能是所声明的类型及以下的类型,那该怎么约束呢,比如:

    很显然该类型是一个不变类型,而如果要要求我们传的类型有上界,则需要这样声明:

    目前这种声明是只支持一种上限,而有时候可能会有多个上界类型,那在Kotlin是如何声明的呢?

    很显然String既是Comparable和Any的子类型,其实Any的声明是可以去掉的,如下:

    但是这是为了演示泛型可以声明多个上限有意为之的。

  • 相关阅读:
    第十一章 前端开发-jQuery
    第十一章 前端开发-JavaScript
    js特效 15个小demo
    开发”小米商城官网首页”(静态页面)
    浅析BFC及其作用
    python mysql curros.executemany 批量添加
    第十一章 前端开发-css
    spark读取文件机制 源码剖析
    zookeeper从入门到放弃(转载学习)
    hbase架构和读写过程
  • 原文地址:https://www.cnblogs.com/webor2006/p/11296775.html
Copyright © 2011-2022 走看看