Kotlin 泛型函數和星投影

 泛型函數

和Java類型,除了泛型類,函數本身也是支持泛型的。

fun <T> getValue(item: T): T {
    return item
}

普通的函數是沒有<T>這部分內容的,表示這個是泛型函數,擁有一個泛型類型T。

 val item = getValue<Int>(100)

 泛型約束

定義好一個泛型,在聲明泛型類的時候指定好泛型的上界。

class UpperBoundeClass<T : List<T>> {

}

指定UpperBoundeClass的泛型是T,要求T只能是列表List以及List下面的類型。

星投影

對於 Foo <out T : TUpper>,其中 T 是一個具有上界 TUpper 的協變類型參數,Foo <*> 等價於 Foo <out TUpper>。 這意味着當 T 未知時,你可以安全地從 Foo <*> 讀取 TUpper 的值。

class Star <out T>{

}
 override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main9)
        val star1 : Star<Number> = Star<Int>()
        val star2 :Star<*> = star1

    }

star1具有上界Number,Star<*>等價於Star <out Number>。如果讀取star2 ,這裏的star2的類型都是Number類型。

對於 Foo <in T>,其中 T 是一個逆變類型參數,Foo <*> 等價於 Foo <in Nothing>。 這意味着當 T 未知時,沒有什麼可以以安全的方式寫入 Foo <*>

class Star2 <in T>{
    fun setValue(t:T){

    }
}
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main9)

        val star2 :Star2<Int> = Star2<Number>()
        val star3 :Star2<*> = star2

        star3.setValue(3)//編譯報錯
    }

對於 Foo <T : TUpper>,其中 T 是一個具有上界 TUpper 的不型變類型參數,Foo<*> 對於讀取值時等價於 Foo<out TUpper> 而對於寫值時等價於 Foo<in Nothing>

class Star3<T>(private var t: T) {
    fun setValue(t: T) {

    }

    fun getValue(): T {
        return this.t
    }
}


override fun onCreate(savedInstanceState: Bundle?) {
     super.onCreate(savedInstanceState)
     setContentView(R.layout.activity_main9)
     val star3: Star3<String> = Star3<String>("hello")
     val star4: Star3<*> = star3
     star4.getValue()
     star4.setValue("world")//編譯錯誤
  }

 

 無法編譯通過,道理和之前的是類型的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章