前置知识

kotlin泛型搞不定很大原因是java泛型不熟悉。

所以在学习Kotlin泛型前,要对Java泛型有充分的认识,已经在另外一篇文章详细介绍了,这里不做解读。

下面关于Any与Any?。

String?的基类是Any?,String的基类是Any,Any的基类又是Any?。

Any和Object是不同的。Any并没有Object的范围大。
Any? 等同于 Object 。

Kotlin泛型

声明处型变(declaration-site variance)与类型投影(type projections)

协变与逆变

? extends相当于out,? super相当于in

逆变性(contravariance)

星投影

泛型函数

不仅类可以有类型参数。函数也可以有。类型参数要放在函数名称之前

PECS法则

参考

1
2
3
4
5
6
7
8
对于 Foo <out T : TUpper>,其中 T 是一个具有上界 TUpper 的协变类型参数,Foo <*> 等价于 Foo <out TUpper>。 这意味着当 T 未知时,你可以安全地从 Foo <*> 读取 TUpper 的值。
对于 Foo <in T>,其中 T 是一个逆变类型参数,Foo <*> 等价于 Foo <in Nothing>。 这意味着当 T 未知时,没有什么可以以安全的方式写入 Foo <*>。
对于 Foo <T : TUpper>,其中 T 是一个具有上界 TUpper 的不型变类型参数,Foo<*> 对于读取值时等价于 Foo<out TUpper> 而对于写值时等价于 Foo<in Nothing>。
如果泛型类型具有多个类型参数,则每个类型参数都可以单独投影。 例如,如果类型被声明为 interface Function <in T, out U>,我们可以想象以下星投影:

Function<*, String> 表示 Function<in Nothing, String>;
Function<Int, *> 表示 Function<Int, out Any?>;
Function<*, *> 表示 Function<in Nothing, out Any?>