泛型函數
和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")//編譯錯誤
}
無法編譯通過,道理和之前的是類型的。