Kotlin基礎(chǔ)-泛型

一郊酒、定義

泛型状蜗,即 "參數(shù)化類型",將類型參數(shù)化除呵,可以用在類再菊,接口,方法上颜曾。
與 Java 一樣纠拔,Kotlin 也提供泛型,為類型安全提供保證泛豪,消除類型強(qiáng)轉(zhuǎn)的煩惱稠诲。
聲明一個(gè)泛型類:

class Box<T>(t: T) {
    var value = t
}

創(chuàng)建類的實(shí)例時(shí)我們需要指定類型參數(shù):

val box: Box<Int> = Box<Int>(1)
// 或者
val box = Box(1) 
// 編譯器會(huì)進(jìn)行類型推斷,1的類型Int诡曙,所以編譯器知道我們說的是 Box<Int>
  • 定義泛型類型變量臀叙,可以完整地寫明類型參數(shù),如果編譯器可以自動(dòng)推定類型參數(shù)价卤,也可以省略類型參數(shù)劝萤。
    Kotlin 泛型函數(shù)的聲明與 Java 相同,類型參數(shù)要放在函數(shù)名的前面:
fun <T> boxIn(value: T) = Box(value)
  • 在調(diào)用泛型函數(shù)時(shí)慎璧,如果可以推斷出類型參數(shù)床嫌,可以省略泛型參數(shù)

二跨释、泛型約束

我們可以使用泛型約束來設(shè)定一個(gè)給定參數(shù)允許使用的類型。
Kotlin 中使用 : 對泛型的類型上限進(jìn)行約束厌处。
最常見的約束是上界(upper bound):

fun <T : Comparable<T>> sort(list: List<T>) {
    // ……
}
  • Comparable 的子類型可以替代 T
  • 默認(rèn)的上界是 Any?鳖谈。
  • 對于多個(gè)上界約束條件,可以用 where 子句:
fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
    where T : CharSequence,
          T : Comparable<T> {
    return list.filter { it > threshold }.map { it.toString() }
}

三阔涉、型變

Kotlin 中沒有通配符類型缆娃,它有兩個(gè)其他的東西:

  • 聲明處型變(declaration-site variance)
  • 類型投影(type projections)

1、聲明處型變

聲明處的類型變異使用協(xié)變注解修飾符:in洒敏、out龄恋,消費(fèi)者 in, 生產(chǎn)者 out。

  • 使用 out 使得一個(gè)類型參數(shù)協(xié)變凶伙,協(xié)變類型參數(shù)只能用作輸出郭毕,可以作為返回值類型但是無法作為入?yún)⒌念愋停?/li>
  • in 使得一個(gè)類型參數(shù)逆變,逆變類型參數(shù)只能用作輸入函荣,可以作為入?yún)⒌念愋偷菬o法作為返回值的類型:
// 定義一個(gè)支持協(xié)變的類
class Runoob<out A>(val a: A) {
    fun foo(): A {
        return a
    }
}

fun main(args: Array<String>) {
    var strCo: Runoob<String> = Runoob("a")
    var anyCo: Runoob<Any> = Runoob<Any>("b")
    anyCo = strCo
    println(anyCo.foo())   // 輸出 a
}

// 定義一個(gè)支持逆變的類
class Runoob<in A>(a: A) {
    fun foo(a: A) {
    }
}

fun main(args: Array<String>) {
    var strDCo = Runoob("a")
    var anyDCo = Runoob<Any>("b")
    strDCo = anyDCo
}

2显押、類型投影

有些時(shí)候, 你可能想表示你并不知道類型參數(shù)的任何信息, 但是仍然希望能夠安全地使用它. 這里所謂"安全地使用"是指, 對泛型類型定義一個(gè)類型投射, 要求這個(gè)泛型類型的所有的實(shí)體實(shí)例, 都是這個(gè)投射的子類型。
對于這個(gè)問題, Kotlin 提供了一種語法, 稱為 星號投射(star-projection):

  • 假如類型定義為 Foo<out T> , 其中 T 是一個(gè)協(xié)變的類型參數(shù), 上界(upper bound)為 TUpper ,Foo<> 等價(jià)于 Foo<out TUpper> . 它表示, 當(dāng) T 未知時(shí), 你可以安全地從 Foo<> 中 讀取TUpper 類型的值.
  • 假如類型定義為 Foo<in T> , 其中 T 是一個(gè)反向協(xié)變的類型參數(shù), Foo<> 等價(jià)于 Foo<inNothing> . 它表示, 當(dāng) T 未知時(shí), 你不能安全地向 Foo<> 寫入 任何東西.
  • 假如類型定義為 Foo<T> , 其中 T 是一個(gè)協(xié)變的類型參數(shù), 上界(upper bound)為 TUpper , 對于讀取值的場合, Foo<*> 等價(jià)于 Foo<out TUpper> , 對于寫入值的場合, 等價(jià)于 Foo<in Nothing> .

如果一個(gè)泛型類型中存在多個(gè)類型參數(shù), 那么每個(gè)類型參數(shù)都可以單獨(dú)的投射. 比如, 如果類型定義為interface Function<in T, out U> , 那么可以出現(xiàn)以下幾種星號投射:

  • Function<*, String> , 代表 Function<in Nothing, String> ;
  • Function<Int, *> , 代表 Function<Int, out Any?> ;
  • Function<, > , 代表 Function<in Nothing, out Any?> .
    注意: 星號投射與 Java 的原生類型(raw type)非常類似, 但可以安全使用
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末傻挂,一起剝皮案震驚了整個(gè)濱河市乘碑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌金拒,老刑警劉巖兽肤,帶你破解...
    沈念sama閱讀 218,941評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異绪抛,居然都是意外死亡资铡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評論 3 395
  • 文/潘曉璐 我一進(jìn)店門幢码,熙熙樓的掌柜王于貴愁眉苦臉地迎上來笤休,“玉大人,你說我怎么就攤上這事症副〉暄牛” “怎么了?”我有些...
    開封第一講書人閱讀 165,345評論 0 356
  • 文/不壞的土叔 我叫張陵贞铣,是天一觀的道長闹啦。 經(jīng)常有香客問我,道長辕坝,這世上最難降的妖魔是什么窍奋? 我笑而不...
    開封第一講書人閱讀 58,851評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上费变,老公的妹妹穿的比我還像新娘。我一直安慰自己圣贸,他們只是感情好挚歧,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吁峻,像睡著了一般滑负。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上用含,一...
    開封第一講書人閱讀 51,688評論 1 305
  • 那天矮慕,我揣著相機(jī)與錄音,去河邊找鬼啄骇。 笑死痴鳄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的缸夹。 我是一名探鬼主播痪寻,決...
    沈念sama閱讀 40,414評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼虽惭!你這毒婦竟也來了橡类?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評論 0 276
  • 序言:老撾萬榮一對情侶失蹤芽唇,失蹤者是張志新(化名)和其女友劉穎顾画,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體匆笤,經(jīng)...
    沈念sama閱讀 45,775評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡研侣,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了疚膊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片义辕。...
    茶點(diǎn)故事閱讀 40,096評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寓盗,靈堂內(nèi)的尸體忽然破棺而出灌砖,到底是詐尸還是另有隱情,我是刑警寧澤傀蚌,帶...
    沈念sama閱讀 35,789評論 5 346
  • 正文 年R本政府宣布基显,位于F島的核電站,受9級特大地震影響善炫,放射性物質(zhì)發(fā)生泄漏撩幽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望窜醉。 院中可真熱鬧宪萄,春花似錦、人聲如沸榨惰。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琅催。三九已至居凶,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間藤抡,已是汗流浹背侠碧。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留缠黍,地道東北人弄兜。 一個(gè)月前我還...
    沈念sama閱讀 48,308評論 3 372
  • 正文 我出身青樓,卻偏偏與公主長得像嫁佳,于是被迫代替她去往敵國和親挨队。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評論 2 355

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

  • Kotlin 中也有泛型的概念蒿往,和 Java 中的類似盛垦,但又不盡相同,一起來認(rèn)識 Kotlin 中的泛型吧瓤漏。 一腾夯、...
    SheHuan閱讀 28,430評論 7 24
  • 與Java一樣,Kotlin也支持泛型蔬充,為類型安全提供保證蝶俱,消除類型強(qiáng)轉(zhuǎn)的煩惱 創(chuàng)建類的實(shí)例時(shí)我們需要指定類型參數(shù)...
    郎官人閱讀 1,240評論 0 0
  • 一、泛型 Kotlin 中的類也可以有類型參數(shù): 二饥漫、型變 聲明處型變(declaration-site vari...
    漆先生閱讀 577評論 0 0
  • 泛型榨呆,即 "參數(shù)化類型",將類型參數(shù)化庸队,可以用在類积蜻,接口,方法上彻消。 與 Java 一樣竿拆,Kotlin 也提供泛型,...
    安卓技術(shù)磚家閱讀 135評論 0 1
  • 系列文章全部為本人的學(xué)習(xí)筆記宾尚,若有任何不妥之處丙笋,隨時(shí)歡迎拍磚指正谢澈。如果你覺得我的文章對你有用,歡迎關(guān)注我御板,我們一起...
    我愛吃栗子啊閱讀 6,738評論 5 14