2017-08-03 45 views
1

我讀的是kotlin沒有通配符的原因(https://kotlinlang.org/docs/reference/generics.htm l)。這一切都來自宣言網站的變化。我們有<in T><out T>結構應該取代通配符。我想我明白<out T>是如何工作的,但我有<in T>的麻煩。初始化變爲只讀列表(儘管不是完全一成不變的原因,我們可以清楚的話),如果我們對待每一個元素號碼可能被讀取後Koltin仿製藥申報網站差異<in T>建設

public List<? extends Number> list1; 
public List<? super String> list2; 

第一種情況:
所以在Java中,我們可以寫這樣的事情。
第二種情況是隻寫(儘管我們可以讀取它,如果我們把每個元素作爲對象)。我們可以在那裏寫上String和它的子類。
在科特林我能夠使用<out T>這樣重新list1的例子:

class Service { 
    val container = Container(mutableListOf("1", "2", "3")) 
} 
class Container<T>(var list1: MutableList<out T>) 

最後我想的東西simmilar與<in T>以爲我能重新列表2的例子,但我失敗了: enter image description here

可有人向我解釋如何在Kotlin中實現我的list2例子?我應該如何正確使用<in T>結構?

回答

3

Kotlin List<E>不等同於Java List<E>。 Java列表具有變異功能,而Kotlin列表是隻讀的。這是相當於Java列表的Kotlin MutableList<E>

下一頁,看看在List<E> declaration:它的類型參數是協變(out E),以及報關現場方差不能使用現場方差來覆蓋,這就是爲什麼你不能有一個List<in T>

此外,聲明現場方差out E意味着E從未出現在一個in位上(有E類型的無功能參數和E類型沒有可變屬性),而事實上,由於List<E>是,它只讀不會將E納入其任何功能(*)

您可以將您的例子來使用,而不是MutableList<E>

class Container2<T>(var list2: MutableList<in T>) 

MutableList<E>接口都有E不變,並in -projection在使用現場不符合申報現場方差衝突。

(*)其實,it does,但只使用標有@UnsafeVariance註釋,它只是抑制變異發生衝突,更多的可以發現here的參數。


此外,小備註:

這一切都來到了聲明站點變化。我們有<in T><out T>結構應該取代通配符。

它實際上是用於替換Java通配符的用戶站點差異。聲明網站差異僅適用於類型參數聲明(類型被定義的地方),並且當它是時,類型的所有用法都會有這種差異(例如,當您使用List<CharSequence>時,它實際上是一個List<out CharSequence>,因爲聲明現場方差爲List<out E>)。因此,使用地點差異對於通用類型的特定用途而言。