Kotlin 泛型(上)

1、前言

<font face= 黑體>在 Kotlin 集合的變換與聚合 中咱們已經將 Kotlin 的 集合變換與聚合 講完了,咱們都知道集合源碼中用到了不少泛型的知識,因此咱們今天咱們來說 Kotlin 的 泛型java

2、泛型

2.一、泛型的基本概念

  • <font face= 黑體>泛型是一種類型層面的抽象;
  • <font face= 黑體>泛型經過泛型參數實現構造更加通用的類型的能力。

<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

2.二、泛型的基本聲明方法

  1. <font face= 黑體>函數聲明泛型:函數

    fun<T> maxOf(a: T, b: T): T
  2. <font face= 黑體>類聲明泛型:code

    sealed calss List<T>

<font face= 黑體>這上面的 T 是形參,當咱們要使用的使用的時候,須要傳進去一個實參 ,以下:接口

val max: String = maxOf<String>("Hello", "World")

// 經過類型推到,上面的代碼能夠簡寫成這樣
val max = maxOf("Hello", "World")

2.三、泛型的約束

<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")

2.四、泛型的多個約束

<font face= 黑體>在咱們實際開發中,有時會遇到一個泛型有多個約束條件的狀況,好比兩個數據既要比較大小,還要執行大的數據類型的 invoke 方法,這時咱們就可使用 Kotlin 爲咱們提供的 where 關鍵字來進行多個條件的約束,具體代碼以下:編譯器

fun <T> callMax(a: T, b: T)
where T : Comparable<T>, T : () -> Unit {
    if (a > b) a() else b()
}

2.五、多個泛型參數

<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>。

2.六、Java 的泛型約束

<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,有須要能夠直接下載。​

相關文章
相關標籤/搜索