Android Kotlin泛型


泛型的基本使用

泛型最常用于類和接口的定義中。例如:
class Box<T>(t: T) {
? ? var value = t
}
val box: Box<Int> = Box(1)
在這個例子中,Box類有一個泛型參數(shù)T传货,這意味著你可以用任何類型來實例化Box伴找,上述代碼中使用的是Int類型蜂厅。

泛型函數(shù)和屬性

你也可以在函數(shù)中使用泛型:
fun <T> singletonList(item: T): List<T> {
? ? return listOf(item)
}
val intList = singletonList(1) // 推斷出 List<Int>
在這里查库,singletonList 是一個泛型函數(shù)鼎姊,它接收一個類型為 T 的參數(shù)屠缭,并返回一個 List<T>箍鼓。

泛型約束
你可以限制泛型參數(shù)的類型范圍,這被稱為“泛型約束”呵曹。使用where關(guān)鍵字可以指定一個泛型必須滿足的一個或多個約束款咖。
fun <T> ensureTrailingPeriod(seq: T)
? ? where T : CharSequence, T : Appendable {
? ? if (!seq.endsWith('.')) {
? ? ? ? seq.append('.')
? ? }
}
val myStringBuilder = StringBuilder("Hi")
ensureTrailingPeriod(myStringBuilder)
在這個例子中,ensureTrailingPeriod 函數(shù)的類型參數(shù) T 必須同時是 CharSequence 和 Appendable 的子類型奄喂。

類型擦除和 reified 類型參數(shù)
Kotlin 中的泛型在運行時會被擦除铐殃,這意味著泛型參數(shù)的具體類型信息在運行時不可用。為了解決這個問題跨新,Kotlin 引入了reified泛型參數(shù)富腊,但它只能在內(nèi)聯(lián)函數(shù)中使用。
inline fun <reified T> isA(value: Any) = value is T
val x = 42
println(isA<Int>(x)) // 輸出 true
在這里域帐,isA函數(shù)使用reified關(guān)鍵字使泛型參數(shù)T在函數(shù)內(nèi)部實際化赘被,從而使得在運行時可以檢查value是否為T類型。

協(xié)變與逆變
Kotlin 支持泛型的協(xié)變與逆變:

協(xié)變(covariance)
允許你將子類型對象的集合賦給父類型對象的集合肖揣。在 Kotlin 中使用?out?關(guān)鍵字來表示協(xié)變民假。
逆變(contravariance)
允許你將父類型對象的集合賦給子類型對象的集合。在 Kotlin 中使用?in?關(guān)鍵字來表示逆變龙优。

協(xié)變描述了這樣一種情況:當(dāng)一個泛型類的類型參數(shù)可以接受其自己或它的子類時羊异,我們稱這個泛型類為協(xié)變的。在協(xié)變中:
- 你有一個泛型容器(比如`List<T>`),它可以持有類型`T`球化。
- 如果這個泛型容器聲明成`List<out T>`秽晚,那么你可以給它傳遞`T`或者`T`的任何子類作為類型參數(shù)。
- 這意味著如果你有`List<Animal>`筒愚,你也可以把`List<Cat>`(假設(shè)`Cat`是`Animal`的子類)當(dāng)作`List<Animal>`來使用赴蝇。

逆變是協(xié)變的反面:當(dāng)一個泛型類的類型參數(shù)可以接受其自己或它的父類時,我們稱這個泛型類為逆變的巢掺。在逆變中:
- 你有一個泛型容器或泛型函數(shù)(如`Consumer<T>`)句伶,它可以接受或操作類型`T`的輸入。
- 如果這個泛型容器或函數(shù)聲明成`Consumer<in T>`陆淀,那么你可以給它傳遞`T`或者`T`的任何父類作為類型參數(shù)考余。
- 這意味著如果你有一個專門處理`Animal`的函數(shù),你可以傳遞`Animal`或者`Animal`的任何超類(比如`Object`)給這個函數(shù)轧苫。

在協(xié)變中楚堤,泛型類容納產(chǎn)生(produce)數(shù)據(jù)的場景,你可以從中讀取數(shù)據(jù)含懊,而在適當(dāng)?shù)那闆r下身冬,子類可以代替父類。在逆變中岔乔,泛型類消費(consume)數(shù)據(jù)的場景酥筝,你可以向其寫入數(shù)據(jù),而在適當(dāng)?shù)那闆r下雏门,父類可以代替子類嘿歌。

舉個簡單的例子,如果你有一個裝蘋果的籃子茁影,這個籃子可以被看作裝水果的籃子是協(xié)變的宙帝;如果你需要一個可以接受任何水果放入的籃子,那個可以接受蘋果放入的籃子就是逆變的募闲。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茄唐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蝇更,更是在濱河造成了極大的恐慌沪编,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件年扩,死亡現(xiàn)場離奇詭異蚁廓,居然都是意外死亡,警方通過查閱死者的電腦和手機厨幻,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門相嵌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來腿时,“玉大人,你說我怎么就攤上這事饭宾∨悖” “怎么了?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵看铆,是天一觀的道長徽鼎。 經(jīng)常有香客問我,道長弹惦,這世上最難降的妖魔是什么否淤? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮棠隐,結(jié)果婚禮上石抡,老公的妹妹穿的比我還像新娘。我一直安慰自己助泽,他們只是感情好啰扛,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗡贺,像睡著了一般隐解。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上暑刃,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音膜眠,去河邊找鬼岩臣。 笑死,一個胖子當(dāng)著我的面吹牛宵膨,可吹牛的內(nèi)容都是我干的架谎。 我是一名探鬼主播令宿,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼跳座,長吁一口氣:“原來是場噩夢啊……” “哼胚鸯!你這毒婦竟也來了概漱?” 一聲冷哼從身側(cè)響起絮吵,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虱咧,失蹤者是張志新(化名)和其女友劉穎否彩,沒想到半個月后舒帮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瑞凑,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡末秃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了籽御。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片练慕。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡惰匙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铃将,到底是詐尸還是另有隱情项鬼,我是刑警寧澤,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布劲阎,位于F島的核電站绘盟,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哪工。R本人自食惡果不足惜奥此,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望雁比。 院中可真熱鬧稚虎,春花似錦、人聲如沸偎捎。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽茴她。三九已至寻拂,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間丈牢,已是汗流浹背祭钉。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留己沛,地道東北人慌核。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像申尼,于是被迫代替她去往敵國和親垮卓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容