【runoob.12】泛型

泛型约束

我们可以使用泛型约束来设定一个给定参数允许使用的类型。
Kotlin 中使用 : 对泛型的的类型上限进行约束。
最常见的约束是上界(upper bound):

fun > sort(list: List) {
    // ……
}

Comparable 的子类型可以替代 T。 例如:

sort(listOf(1, 2, 3)) // OK。Int 是 Comparable 的子类型
sort(listOf(HashMap())) // 错误:HashMap 不是 Comparable> 的子类型

默认的上界是 Any?。
对于多个上界约束条件,可以用 where 子句:

fun  cloneWhenGreater(list: List, threshold: T): List
    where T : Comparable, Cloneable {
      return list.filter(it > threshold).map(it.clone())
    }

星号投射

有些时候, 你可能想表示你并不知道类型参数的任何信息, 但是仍然希望能够安全地使用它. 这里所谓"安全地使用"是指, 对泛型类型定义一个类型投射, 要求这个泛型类型的所有的实体实例, 都是这个投射的子类型。
对于这个问题, Kotlin 提供了一种语法, 称为 星号投射(star-projection):

  • 假如类型定义为 Foo , 其中 T 是一个协变的类型参数, 上界(upper bound)为 TUpper ,Foo<> 等价于 Foo . 它表示, 当 T 未知时, 你可以安全地从 Foo<> 中 读取TUpper 类型的值.
  • 假如类型定义为 Foo , 其中 T 是一个反向协变的类型参数, Foo<> 等价于 Foo . 它表示, 当 T 未知时, 你不能安全地向 Foo<> 写入 任何东西.
  • 假如类型定义为 Foo , 其中 T 是一个协变的类型参数, 上界(upper bound)为 TUpper , 对于读取值的场合, Foo<*> 等价于 Foo , 对于写入值的场合, 等价于 Foo .

如果一个泛型类型中存在多个类型参数, 那么每个类型参数都可以单独的投射. 比如, 如果类型定义为interface Function , 那么可以出现以下几种星号投射:

  • Function<*, String> , 代表 Function ;
  • Function , 代表 Function ;
  • Function<, > , 代表 Function .

注意: 星号投射与 Java 的原生类型(raw type)非常类似, 但可以安全使用

你可能感兴趣的:(【runoob.12】泛型)