Koltin 高級篇 Lambda 簡潔之道

序言

最近一直在學習 kotlin 饼疙,他給我的感覺是一門非常使用俭茧、簡潔的語言挺物。Kotlin 支持函數(shù)式編程豪椿,而 Lambda 在 Kotlin 和 Kotlin DSL 中扮演著很重要的角色,是實現(xiàn)整潔代碼的必備語法糖叨恨。

Lambda 表達式的語法

一個 lambda 把一小段行為進行編碼柳刮,你能把它當作值到處傳遞。它可以被獨立地聲明并存儲到一個變量中痒钝,但是更常見的還是直接聲明它井傳遞給函數(shù)(高階函數(shù))秉颗。

Kotlin in Action

Kotlin lambda 表達式始終用花括號包圍。注意實參并沒有用括號括起來
頭把實參列表和 lambda 的函數(shù)體隔開送矩。

高階函數(shù)

就是這個函數(shù)可以接受另一個函數(shù)作為參數(shù)或者返回值
函數(shù)的形參總是 首先是括號里面是函數(shù)的入?yún)㈩愋筒仙缓蠹^后面跟的是函數(shù)返回值類型,沒有返回值要指定 Unit 如圖:

Kotlin in Action

下面是一個 Android 中最常見的 view 的點擊事件在 分別用 java 和 kotlin 來實現(xiàn)

java 寫法
// java 1栋荸、首先要聲明接口 2菇怀、實例這個接口創(chuàng)建一個匿名內(nèi)部類
public interface OnClickListener {
    void onClick(View v);
}

button.setOnClickListener(new OnClickListener() {
  @Override
  public void onClick (View view) {
  /*點擊后執(zhí)行的動作*/
  } 
)
kotlin lambda 寫法
// kotlin 高級函數(shù)聲明( 傳入 lambda )  view 類型參數(shù) 沒有返回值
fun setOnClickListener(listener: (View) -> Unit)
// kotlin 十分簡潔
button.setOnClickListener({ v: View -> print(v.name)})
kotlin lambda 如果這個函數(shù)的最后一個參數(shù)是一個函數(shù),我們可以把這個函數(shù)移動到圓括號外面
button.setOnClickListener() { v: View -> print(v.name)}
kotlin lambda 如果這個函數(shù)只有一個參數(shù)晌块,我們可以省略這個圓括號
button.setOnClickListener{ v: View -> print(v.name)}
// 用 it 代替參數(shù)
button.setOnClickListener{ print(it.name)}
// 如果沒有用到 v 這個參數(shù)可以進一步簡化
button.setOnClickListener { print("我就是簡潔...")}

我們將會在下一章中講解 lambda 表達式的經(jīng)典用途和集合一起工作爱沟,kotlin 是如何提供那么方便的集合庫

帶接收者的 lambda 和擴展函數(shù)類型

首先我們還是先通過 來看為啥要用這個帶接收者的 lambda,他是怎么做到優(yōu)化的匆背。
1呼伸、先定義一個個以普通 lambda 作為參數(shù)的 buildString 函數(shù)。

/**
* @param builderAction 定義函數(shù)類型的參數(shù)
*/
fun buildStringNormalLm(builderAction: (StringBuilder) -> Unit): String {
      val sb = java.lang.StringBuilder()
      // 傳遞一個 StringBuilder 對象作為 lambda 的參數(shù)
      builderAction(sb)
      return sb.toString()
}
 //  調(diào)用普通的 lambda
val s = buildStringNormalLm {
      it.append("Hello,")
      it.append("World")
}
print(s)
// 打印結(jié)果 Hello,World

2钝尸、首先 it 這個對象執(zhí)行多次操作括享,我們不想反復把對象的名稱寫出來 就是未來這個目的....
3搂根、要做到這點,需要將 lambda 轉(zhuǎn)換成帶接收者的 lambda铃辖。

/**
* @param builderAction 定義帶接收者的函數(shù)類型的參數(shù)
*  StringBuilder. () -> Unit 擴展函數(shù)聲明
*/
fun buildStringReceiverLm(builderAction: StringBuilder. () -> Unit): String {
      val sb = java.lang.StringBuilder()
      // 傳遞一個 String Builder 實例作為 lambda 接收者
      sb.builderAction()
      return sb.toString()
}
// 調(diào)用帶接收者的 lambda
val s = buildStringReceiverLm {
       append("Hello,")
       append("World")
}
print(s)
// 打印結(jié)果 Hello,World

那為什么在 buildStringReceiverLm() 中可以直接調(diào)用 StringBuilder 實例那 剩愧?

  • 主要是我們用 擴展函數(shù)類型 取代 普通函數(shù)類型 來聲明參數(shù)的類型 。擴展函數(shù)類型的聲明如下圖:
    Kotlin in Action

為什么要用擴展函數(shù)類型澳叉?不需要顯式的修飾符就可以訪問一個外部類型的成
員讓我們想起了擴展函數(shù)隙咸,它可以讓我們?yōu)樵诖a其他地方定義的類定義自己的方法沐悦。擴展函數(shù)和帶接收者的 lambda 都有一個接收者對象 成洗,當函數(shù)被調(diào)用的時候需要提供這個對象,它在函數(shù)體內(nèi)是可用的藏否。實際上一個個擴展函數(shù)類型描述了可以被當作擴展函數(shù)來調(diào)用的代碼塊瓶殃。

仔細看下面的截圖以及備注我想你一定能看明白

下一節(jié)我們會通過展示 Kotlin 標準庫中的 with 函數(shù)和 apply 函數(shù),來進一步說明 帶接收者的 lambda 實際項目中用到的地方副签。

參考資料

Kotlin之美——DSL篇
《Kotlin 實戰(zhàn)》

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末遥椿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子淆储,更是在濱河造成了極大的恐慌冠场,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件本砰,死亡現(xiàn)場離奇詭異碴裙,居然都是意外死亡,警方通過查閱死者的電腦和手機点额,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進店門舔株,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人还棱,你說我怎么就攤上這事载慈。” “怎么了珍手?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵办铡,是天一觀的道長。 經(jīng)常有香客問我琳要,道長寡具,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任焙蹭,我火速辦了婚禮晒杈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘孔厉。我一直安慰自己拯钻,他們只是感情好帖努,可當我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著粪般,像睡著了一般拼余。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上亩歹,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天匙监,我揣著相機與錄音,去河邊找鬼小作。 笑死亭姥,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的顾稀。 我是一名探鬼主播达罗,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼静秆!你這毒婦竟也來了粮揉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤抚笔,失蹤者是張志新(化名)和其女友劉穎扶认,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體殊橙,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡辐宾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了蛀柴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片螃概。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鸽疾,靈堂內(nèi)的尸體忽然破棺而出吊洼,到底是詐尸還是另有隱情,我是刑警寧澤制肮,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布冒窍,位于F島的核電站,受9級特大地震影響豺鼻,放射性物質(zhì)發(fā)生泄漏综液。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一儒飒、第九天 我趴在偏房一處隱蔽的房頂上張望谬莹。 院中可真熱鬧,春花似錦、人聲如沸附帽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕉扮。三九已至整胃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間喳钟,已是汗流浹背屁使。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留奔则,地道東北人蛮寂。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像应狱,于是被迫代替她去往敵國和親共郭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,700評論 2 354