美文网首页
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 Weekly 中文周报 —— 23

    Kotlin 开发中文周报 文章 Kotlin 泛型『in』和『out』的变体(android.jlelse.eu...

  • Kotlin泛型变体

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

  • 泛型

    与Java泛型相同,Kotlin同样提供了泛型支持。对于简单的泛型类、泛型函数的定义,Kotlin 与 Java ...

  • Kotlin---泛型

    Kotlin不变型泛型 Kotlin的不变型泛型和Java一样,通过声明泛型类型来使用泛型类。而该种泛型声明后,则...

  • Kotlin 泛型 VS Java 泛型

    建议先阅读我的上一篇文章 -- Java 泛型 和 Java 泛型一样,Kotlin 泛型也是 Kotlin 语言...

  • Kotlin for android学习六:泛型

    前言 kotlin官网和kotlin教程学习教程的笔记。 1. 声明泛型 2. 泛型约束 : 对泛型的类型上限进行...

  • 泛型

    Kotlin 泛型详解 声明一个泛型类 声明一个泛型方法 泛型约束 List 和 List 是...

  • Kotlin 泛型

    Kotlin 支持泛型, 语法和 Java 类似。例如,泛型类: 泛型函数: 类型变异 Java 的泛型中,最难理...

  • Kotlin:泛型杂谈(下)

    在Kotlin:泛型杂谈(上)中,从泛型扩展属性、非空约束、实例化类型参数三个方面简单介绍了一下Kotlin中泛型...

  • 【Android】 Kotlin(七)泛型

    深入理解Kotlin泛型 Kotlin 的泛型与 Java 一样,都是一种语法糖,即只在源代码中有泛型定义,到了c...

网友评论

      本文标题:Kotlin泛型变体

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