Kotlin筆記之泛型(一)

類型參數

泛型允許定義帶類型形參的類型,當這種類型的實例被創建出來的時候,類型形參被替換成稱爲類型實參的具體類型

實例

// 源碼listOf函數聲明
fun <T> listOf(vararg elements: T): List<T>

val list=listOf("hello","world") // 編譯器推導

val list= listOf<String>()// 顯示說明

上例中 T類型形參 ,並且函數的返回類型使用了類型形參

區別

  • Kotlin 要求類型實參要麼被顯示地說明,要麼能被編譯器推導推導出來
  • Kotlin 不支持原生態類型,類型實參必須定義
  • Java 允許使用沒有類型參數的泛型類型(原生態類型),因爲支持老版本代碼兼容

泛型類和函數

泛型類

Kotlin 通過在類名稱後加上一對尖對號,並把類型參數放在尖對號內來聲明泛型類及泛型接口。一旦聲明之後,就可以在類的主體內像其他類型一樣使用類型參數。

// 泛型類
class Gen<T>(private var t: T) {
    fun  getValue() :T{
        return t
    }
}

// 泛型接口
interface List<T>{
  public operator fun get(index: Int): T
}

小結: 如果類繼承了泛型類(實現了泛型接口),就得爲基礎類型的泛型形參提供了一個類型實參,它可以是具體類型或者另一個類型形參:

class GenList:List<String>{
 override fun get(index :Int):String=...
}

class ArrayList<T>:List<T>{
override fun get(index :Int):T=...
}

泛型函數

泛型函數有它自己的類型形參,這些類型形參在每次函數調用時都必須替換成具體的類型實參

fun <T> printMessage(msg :T){
    when (content) {
       is Int ->{"該信息數據類型是整型"}
       else ->{"該信息數據類型不是整型"}
    }
}

注意: 普通(即非拓展)屬性不能擁有類型參數,不能在一個類的屬性中存儲多個不同類型的值,因此聲明泛型非拓展函數沒有任何意義

類型參數約束

類型參數約束可以限制作爲泛型類和泛型函數的類型實參的類型;如果把一個類型指定爲泛型類型形參的上界約束,在泛型類型具體的初始化中,其對應的類型實參就必須是這個具體類型或者它的子類型

示例

// 函數聲明
fun <T:Number> List<T>.sum() :T

// 具體類型實參繼承了Number,函數調用是允許的
println(listOf(1,2,3).sum())

上例中,通過在類型參數後指定上界來定義約束,把冒號放在類型參數名稱之後,作爲類型形參上界的類型緊隨其後;一旦指定了類型形參T的上界,就可以把類型T的值當作它的上界(類型)的值使用

類型參數非空、可空

如果聲明的是泛型類或者泛型函數,任何類型實參,包括那些可空的類型實參,都可以替換它的類型形參;沒有指定上界的類型形參將會使用Any?這個默認上界


// 類型參數可空  默認上界的類型形參是Any?
class Person<T>{
  fun name(value :T){
    value?.hashcode()
  }
}

// 類型參數非空   默認上界的類型形參是Any
class Person<T:Any>{
  fun name(value :T){
    value?.hashcode()
  }
}

注意:可以通過指定任意非空類型作爲上界,來讓類型參數非空,不光是類型Any

發佈了24 篇原創文章 · 獲贊 1 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章