Kotlin-泛型

關于什么是泛型, 看另一篇文章 http://www.reibang.com/p/7eac2f36036e

參數(shù)化函數(shù)(泛型函數(shù))

  1. 在函數(shù)名前邊加上<T>實現(xiàn)參數(shù)化函數(shù)
  2. 函數(shù)的參數(shù)至少有一個是T類型, 否則編譯器無法推斷出T的類型
fun <T> foo (input: T): T {
    return input
}

函數(shù)的返回值可以是任何類型, 但不能用運行時的類型

fun <T> foo (input: T): String {
    return input // 即使我們在運行時傳入了一個字符串也不行, input的類型是T, 與運行時的類型無關
}

參數(shù)化類型

參數(shù)化類型主要用在各種容器類型上, 這種類型內(nèi)部可以包含其他類型的數(shù)據(jù), 比如list, map

class Sequence<T> // 定義一個參數(shù)化類型
val seq = Sequence<Int>() //傳入Int類型

上界類型約束

將類型限制為某個類的子類, 如果省略, 將會是Any

fun <T: Number> convert(a: T, b: T)  // 將T的類型限制為Number的子類
fun <T> convert(a: T, b: T)  // T的類型限制為Any

Invariance (不變)

類型不變指泛型類型默認是沒有繼承上的關系的, M<Int>并不是M<Number>的一個子類型.
這樣設計的原因, 參考這個例子:

fun foo(m: M<Number>): Unit {
  m.add(123L)
}

假設有一個M<Int>型的集合x, 執(zhí)行foo(x)后, 如果類型有繼承關系, 由于IntLong都是Number的子類型, 就會往x里添加一個Long型元素, 這違背了類型安全的原則.

Covariance (協(xié)變)

協(xié)變是改變類型之間的關系, 使他們有繼承性.

fun foo(m: M<Number>): Unit {
  m.functionFromNumber()
}

假設foo函數(shù)會調(diào)用一個Number類的方法, 這樣我們就不用管傳入的是m<int>, 還是m<Long>都無所謂(因為函數(shù)定義在父類上), 此時就需要協(xié)變`來讓類型有繼承關系.

class M<out T>

使用outT定義為協(xié)變類型之后, 不能用T作為函數(shù)的輸入?yún)?shù)(形參), 可以做返回值. 像m.add(T)是非法的.

逆變 Contravariance

逆變是反轉兩個類的繼承關系, 比如逆變后, M<Int> 是 M<Number> 的父類.

這個需求是這樣的

Event<String>(stringHandler)
Event<Number>(numberHandler)

我們有兩種Event, 分別用對應類型的Handler處理, 假設我們想用一個通用的handler比如: commonHandler<Any>`來處理.

Event<String>(commonHandler)
Event<Number>(commonHandler)

答案是不行, 因為AnyString的父類, 而Event只能使用String或它的子類. 通過逆變, Any就變成了String的子類.

class Event<in T>(val handler: Handler<T>)
class Handler<in T>
...

逆變后, 類型只能作為輸入?yún)?shù)(形參), 不能作為返回值類型.

type projection

類型的variance有兩種, use site(java) 和 declaration site(Kotlin), type projection 允許我們使用use site variance, 它的思想是, 如果我們無法在類定義(比如使用別人的類)時使用covariance或contravriance(即declaration site), 我們可以在定義函數(shù)時, 規(guī)定函數(shù)將如何使用類型.

fun foo(m: M<out Number>): Unit {
  m.functionFromNumber()
}

同理, contravariant

class Event<in T>(val handler: Handler<in T>) // 構造函數(shù)的in T

type projection定義了我們?nèi)绾问褂煤瘮?shù), 而不需修改原類型聲明

Type reification

由于JVM在編譯時會把所有泛型類型(不包括基礎數(shù)據(jù)類型)信息擦除, kotlin同樣如此, 使用Type reification, kotlin可以為inline 函數(shù)保留泛型類型信息.

inline fun <reified T>printT(any: Any): Unit {
    if (any is T)
    println("I am a tee: $any")
}

這個函數(shù)可以在運行時獲取到T的傳入類型. 類型具體化只能用于inline函數(shù), 因為inline函數(shù)的執(zhí)行是把函數(shù)體內(nèi)容直接拷貝到調(diào)用處, 此時通過傳遞的參數(shù)可以知道T的類型. 其他函數(shù)無法使用類型具體化

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沥阳,隨后出現(xiàn)的幾起案子啰劲,更是在濱河造成了極大的恐慌醉者,老刑警劉巖铃慷,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異藕施,居然都是意外死亡摩幔,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門铐尚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拨脉,“玉大人,你說我怎么就攤上這事宣增∶蛋颍” “怎么了?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵爹脾,是天一觀的道長帖旨。 經(jīng)常有香客問我,道長灵妨,這世上最難降的妖魔是什么解阅? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮泌霍,結果婚禮上货抄,老公的妹妹穿的比我還像新娘。我一直安慰自己朱转,他們只是感情好蟹地,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著藤为,像睡著了一般锈津。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凉蜂,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天琼梆,我揣著相機與錄音性誉,去河邊找鬼。 笑死茎杂,一個胖子當著我的面吹牛错览,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播煌往,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼倾哺,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了刽脖?” 一聲冷哼從身側響起羞海,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎曲管,沒想到半個月后却邓,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡院水,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年腊徙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片檬某。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡撬腾,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出恢恼,到底是詐尸還是另有隱情民傻,我是刑警寧澤,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布场斑,位于F島的核電站漓踢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏和簸。R本人自食惡果不足惜彭雾,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一碟刺、第九天 我趴在偏房一處隱蔽的房頂上張望锁保。 院中可真熱鬧,春花似錦半沽、人聲如沸爽柒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浩村。三九已至,卻和暖如春占哟,著一層夾襖步出監(jiān)牢的瞬間心墅,已是汗流浹背酿矢。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留怎燥,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像画恰,于是被迫代替她去往敵國和親妥泉。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

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

  • 泛型 泛型(Generic Type)簡介 通常情況的類和函數(shù),我們只需要使用具體的類型即可:要么是基本類型依许,要么...
    Tenderness4閱讀 1,421評論 4 2
  • 本博文主要講解一些Kotlin泛型的問題棺禾,中間會對比穿插Java泛型。 1. 泛型類型參數(shù) 1.1 形式 我們使用...
    24K男閱讀 18,445評論 4 11
  • 轉載文章悍手,出處: https://blog.kotliner.cn/2017/06/26/kotlin-gener...
    _10_01_閱讀 693評論 0 0
  • 與Java一樣帘睦,Kotlin也支持泛型,為類型安全提供保證坦康,消除類型強轉的煩惱 創(chuàng)建類的實例時我們需要指定類型參數(shù)...
    郎官人閱讀 1,242評論 0 0
  • 文~小丸子 2017-7-16 周日 糾結了一會竣付,還是爬起來坐到電腦前面了。 近期滞欠,其實很多次有些想法古胆,想寫下來。...
    云淡風輕小丸子閱讀 232評論 0 0