美文网首页
Kotlin泛型变体

Kotlin泛型变体

作者: Wavky | 来源:发表于2018-04-27 00:39 被阅读0次

    Extends协变

    extends 限定(上界)的通配符类型使得类型是 协变的(covariant),只能接受指定泛类型的子类型

    定义为协变泛型时,实例化前无法确定子类型,泛型内部在实例化时使用实例类型作为容器类型,对该泛型实例对象无法写入存储实例类型的任何父类型,但可安全读取访问(右侧)其内部对象(总是可以安全地将泛型变量值转换为上界父类型)

    只能 读取 的对象为 生产者,Kotlin中使用out修饰符标记,并且该类型对象只能出现在输出(右侧)位置,类Source则作为类型T的生产者

    协变参数类型在泛型中得到维持,在 Collection<out E> 定义中, Collection<Number>Collection<Int> 的父类。

    abstract class Source<out T> {
        abstract fun nextT(): T
    }
    
    fun demo(strs: Source<String>) {
        val objects: Source<Any> = strs // This is OK, since T is an out-parameter
        // ...
    }
    

    Super逆变

    super 限定(下界)的通配符类型使得类型是 逆变的(covariant),只能接受指定泛类型的父类型

    定义为逆变泛型时,可知其最大子类型为Object / Any,泛型内部使用Object / Any类型作为容器类型,对该泛型对象的实例写入存储(左侧)是安全的(总是可以确定对象类型为容器的子类型,但访问时由于类型信息丢失,无法自动转换为其原本子类型)

    只能 写入 的对象为 消费者,Kotlin中使用in修饰符标记,并且该类型对象只能出现在输入(左侧)位置,类Comparable则作为类型T的消费者

    abstract class Comparable<in T> {
        abstract fun compareTo(other: T): Int
    }
    
    fun fill(dest: Array<in String>, value: String) {
        // ...
    }
    

    不变

    不变参数在泛型中,继承关系不被泛型维持,如在 MutableCollection<E> 定义中,MutableCollection<Number>MutableCollection<Int> 不存在继承关系。

    投影

    指在实例化、作为参数类型声明时,对泛类型可接受变体(协变、逆变)的具体指定

    fun copy(from: Array<out Any>, to: Array<Any>) {
        // from 等同于 Array<? extends Object>
    }
    
    fun fill(dest: Array<in String>, value: String) {
        // dest 等同于 Array<? super String>
    }
    

    星投影

    指在实例化、参数类型声明时,使用*代替具体的类型指定(表示任意类型)

    Foo<*>
    Function<*, String>
    Function<*, *>
    

    当泛型定义为<out T : TUpper>时(TTUpper的子类型),使用<*>声明实例相当于声明为<out TUpper>

    当泛型定义为<in T>时,使用<*>声明实例相当于声明为<in Nothing>,该实例无法安全存储任何对象

    当泛型定义为<T : TUpper>时(T类型为TUpper),使用<*>声明实例,在读取访问时相当于声明为<out TUpper>,在写入存储时相当于声明为<in Nothing>

    泛型约束

    通常为指定上界约束

    class Foo<out T : TUpper> {
      // T 是上界为 TUpper 的子类型
      // 并且作为生产者只能用于只读访问(使用 TUpper 作为访问接口类型)
    }
    
    fun <T : Comparable<T>> sort(list: List<T>) {
        // 只有 Comparable<T> 的子类型可传递至该方法
    }
    sort(listOf(1, 2, 3)) // OK. Int is a subtype of Comparable<Int>
    

    不指定上界时,默认为Any?类型

    当需要指定多于一个上界约束时,使用where关键字

    fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
        where T : CharSequence,
              T : Comparable<T> {
        return list.filter { it > threshold }.map { it.toString() }
    }
    

    泛型
    Generics
    Kotlin 泛型

    相关文章

      网友评论

          本文标题:Kotlin泛型变体

          本文链接:https://www.haomeiwen.com/subject/jvmvlftx.html