Kotlin基礎(chǔ)學(xué)習(xí)之lambda中return語句詳解
前言
當(dāng)我們愛上lambda并且大范圍使用它的時(shí)候,我想大家都會(huì)被lambda中的return語句狠狠地調(diào)戲過,所以今天我們需要一起來揭開lambda中return的神秘面紗。
首先來看一個(gè)例子:
fun demo() { val indexes = arrayOf(1, 2, 3, 4, 5, 6, 7) indexes.forEach { if (it > 5) { return } println(it) } println("End") }
按照我們的預(yù)期,調(diào)用demo后,它應(yīng)該輸出:
1
2
3
4
5
End
事實(shí)真是如此嗎?大家可以運(yùn)行一下上面的代碼,它的實(shí)際輸出是:
1
2
3
4
5
什么鬼?那個(gè)End被運(yùn)行時(shí)給偷吃了嗎?不是,為了說明其中的緣由,讓我們看一下forEach的定義:
public inline fun <T> Array<out T>.forEach(action: (T) -> Unit): Unit { for (element in this) action(element) }
從定義中,我們可以看到forEach函數(shù)被定義為了內(nèi)聯(lián)函數(shù),而根據(jù)帶有l(wèi)ambda的內(nèi)聯(lián)函數(shù)處理機(jī)制(相關(guān)講解可參考:Kotlin:關(guān)于內(nèi)聯(lián)函數(shù)的一些理解),我們的demo因?yàn)楸粌?nèi)聯(lián)最終會(huì)被編譯為:
fun demo() { val indexes = arrayOf(1, 2, 3, 4, 5, 6, 7) for (element in indexes) { if (element > 5) { return } println(element) } println("End") }
從最終編譯后的代碼中我們可以很清楚的發(fā)現(xiàn),最后的End不是被偷吃了,而是因?yàn)閐emo函數(shù)在判斷條件滿足的情況下提前返回了,這樣的return用高端一點(diǎn)的語句就叫做:非局部返回。
如果我們想要return從forEach(即lambda)中返回怎么辦?讓我們先改造一下上面對(duì)forEach的調(diào)用:
indexes.forEach { if (it > 5) { return@forEach } println(it) }
再次運(yùn)行一下 demo:
1
2
3
4
5
End
這個(gè)時(shí)候的輸出就跟我們的預(yù)期一樣了,很神奇對(duì)不對(duì)?我們只要在return后面加一個(gè)@forEach就可以了,這就是所謂標(biāo)簽返回(或局部返回),其完整的語法如下:
indexes.forEach label@ { if (it > 5) { return@label } println(it) }
如果我們省略forEach后面label的定義,那么默認(rèn)的label就是把lambda作為參數(shù)的函數(shù)名(這里是forEach)。
這就是lambda中return語句的所有內(nèi)容,很簡(jiǎn)單是不是?接下來就是盡情玩耍的時(shí)間了?別著急,這里還有一些注意事項(xiàng),比如:
fun doSomething(action: () -> Unit) { action() } inline fun doOtherThing(action: () -> Unit) { action() } fun main(args: Array<String>) { doSomething { return } } fun main(args: Array<String>) { var action = { return } doOtherThing(action) }
運(yùn)行上面的例子會(huì)得到怎樣的輸出?不好意思,這個(gè)調(diào)用會(huì)因?yàn)榫幾g失敗不給你運(yùn)行的機(jī)會(huì),
通過上面的討論我們知道,非局部返回是從lambda調(diào)用點(diǎn)所在的函數(shù)中返回,所以這就要求我們lambda中的return語句只能出現(xiàn)在內(nèi)聯(lián)函數(shù)且該lambda表達(dá)式以參數(shù)形式直接傳遞給該函數(shù)的情況,其他情況不允許則是因?yàn)閘ambda可以綁定給一個(gè)變量以便在函數(shù)返回后繼續(xù)使用(比如閉包),而這個(gè)時(shí)候的return已經(jīng)為時(shí)已晚。
好了,關(guān)于lambda控制流的內(nèi)容就討論到這里了,最后祝愿大家快樂coding ^ _ ^
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能示例
這篇文章主要介紹了Android開發(fā)實(shí)現(xiàn)的標(biāo)準(zhǔn)體重計(jì)算器功能,結(jié)合實(shí)例形式分析了Android體重計(jì)算器的界面布局與功能實(shí)現(xiàn)相關(guān)操作技巧,需要的朋友可以參考下2017-12-12android onTouchEvent處理機(jī)制總結(jié)(必看)
下面小編就為大家?guī)硪黄猘ndroid onTouchEvent處理機(jī)制總結(jié)(必看)小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04Android Zxing生成二維碼經(jīng)典案例分享
這篇文章主要為大家分享了Android Zxing生成二維碼經(jīng)典案例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11android實(shí)現(xiàn)緩存圖片等數(shù)據(jù)
本文給大家分享的是Android采用LinkedHashMap自帶的LRU 算法緩存數(shù)據(jù)的方法和示例,有需要的小伙伴可以參考下。2015-07-07Android中TextView局部變色功能實(shí)現(xiàn)
這篇文章給大家詳細(xì)講解了一下Android中TextView實(shí)現(xiàn)部分文字不同顏色的功能實(shí)現(xiàn)過程,有這方面需要的朋友們一起學(xué)習(xí)下吧。2017-12-12Android中Serializable和Parcelable序列化對(duì)象詳解
這篇文章主要介紹了Android中Serializable和Parcelable序列化對(duì)象的相關(guān)資料,感興趣的小伙伴們可以參考一下2016-02-02Android getReadableDatabase() 和 getWritableDatabase()分析對(duì)比
這篇文章主要介紹了Android getReadableDatabase() 和 getWritableDatabase()分析對(duì)比的相關(guān)資料,需要的朋友可以參考下2017-06-06Android自定義View實(shí)現(xiàn)圓形切圖效果
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)圓形切圖效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-12-12Android 使用SwipeRefreshLayout控件仿抖音做的視頻下拉刷新效果
這篇文章主要介紹了Android 使用SwipeRefreshLayout控件仿抖音做的視頻下拉刷新效果,需要的朋友可以參考下2018-05-05