<font face= 黑体>在 Kotlin 集合的变换与聚合 中咱们已经将 Kotlin 的 集合变换与聚合 讲完了,咱们都知道集合源码中用到了不少泛型的知识,因此咱们今天咱们来说 Kotlin 的 泛型。java
<font face= 黑体>比较两个整型的大小 Kotlin 代码能够这样写:git
val max = maxOf(1, 2)
<font face= 黑体>maxOf() 的方法是这样的:github
inline fun maxOf(a: Int, b: Int): Int
<font face= 黑体>可是呢,上面的 maxOf() 方法只能比较两个整型的大小,若是咱们要比较任意类型(好比 Double 等)大小的方法要怎么办呢?因此泛型就是用来实现这种需求的,以下:segmentfault
inline fun<T> maxOf(a: T, b: T): T
<font face= 黑体>函数声明泛型:函数
fun<T> maxOf(a: T, b: T): T
<font face= 黑体>类声明泛型:code
sealed calss List<T>
<font face= 黑体>这上面的 T 是形参,当咱们要使用的使用的时候,须要传进去一个实参 ,以下:接口
val max: String = maxOf<String>("Hello", "World") // 经过类型推到,上面的代码能够简写成这样 val max = maxOf("Hello", "World")
<font face= 黑体>当一个泛型参数没有任何约束时,它能够进行的操做和运算是很是有限的,由于不能对实参作任何类型上的保证,这时候就须要用到泛型的约束。泛型的约束是指泛型的实参必须知足必定的规范,编译器在编译的过程当中能够根据约束来检查全部泛型类型的实参并确保其知足约束条件。
<font face= 黑体>上面咱们讲了一个比较任意类型大小的函数,以下:开发
fun<T> maxOf(a: T, b: T): T { // 编译报错 return if(a > b) a else b }
<font face= 黑体>显然,上面的代码会报错,a 和 b 都是泛型,不能够用 > 号,这时候,咱们能够给泛型 T 加一个 Comparable 约束,就能够实现 a > b,这时候 T 须要实现 Comparable 接口,代码以下所示:get
fun<T : Comparable<T>> maxOf(a: T, b: T): T { return if(a > b) a else b } // String 已经实现类 Comparable 接口,因此能够直接用 val max = maxOf("Hello", "World")
<font face= 黑体>在咱们实际开发中,有时会遇到一个泛型有多个约束条件的状况,好比两个数据既要比较大小,还要执行大的数据类型的 invoke 方法,这时咱们就可使用 Kotlin 为咱们提供的 where 关键字来进行多个条件的约束,具体代码以下:编译器
fun <T> callMax(a: T, b: T) where T : Comparable<T>, T : () -> Unit { if (a > b) a() else b() }
<font face= 黑体>咱们有这样一个需求:比较两个 T 类型的数据大小,并调用大 T 的 invoke 方法,并返回一个 R 类型的数据,这时就要使用多个泛型参数了,代码以下:
fun <T, R> callMax(a: T, b: T): R where T : Comparable<T>, T : () -> R, R : Number { return if (a > b) a() else b() }
<font face= 黑体>多个泛型参数的例子咱们平时用的最多的就是 Map<K, V>。
<font face= 黑体>泛型约束的概念 Java 也有,写法是 T extends ... 咱们来看一下:
public static <T extends Comparable<T>> T maxOf(T a, T b) { if (a.compareTo(b) > 0) return a; else return b; }
源码 已上传至 github,有须要能够直接下载。