Kotlin彙總4-泛型

Java的泛型比較弱,如下面代碼

// Java
List<String> strs = new ArrayList<String>();
List<Object> objs = strs; // !!! The cause of the upcoming problem sits here. Java prohibits this!
objs.add(1); // Here we put an Integer into a list of Strings
String s = strs.get(0); // !!! ClassCastException: Cannot cast Integer to String
//List<String>不能被cast成List<Object>

所以Java引入了通配符的概念

// Java
interface Collection<E> ... {
  void addAll(Collection<? extends E> items);
}

kotlin爲了解決這個泛型問題,引入了C#中的in/out機制。

abstract class Source<out T> {
    abstract fun nextT(): T
}

fun demo(strs: Source<String>) {
    val objects: Source<Any> = strs // This is OK, since T is an out-parameter
    // ...
}
//out:相當於<? extends T>,那麼使用out修飾泛型T後,Source<String>可以被cast成Source<Any>
abstract class Comparable<in T> {
    abstract fun compareTo(other: T): Int
}

fun demo(x: Comparable<Number>) {
    x.compareTo(1.0) // 1.0 has type Double, which is a subtype of Number
    // Thus, we can assign x to a variable of type Comparable<Double>
    val y: Comparable<Double> = x // OK!
}
//in:相當於<? super T>,所以泛型T被in修飾後,Comparable<Number>可以被cast被Comparable<Double>

當你不知道具體類型時可以使用*配符

Function<*, String> means Function<in Nothing, String>

Function<Int, *> means Function<Int, out Any?>

Function<*, *> means Function<in Nothing, out Any?>

泛型理解起來會比較複雜,需要自己寫代碼理解。

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