一文弄懂 kotlin lambda與高階函數(進階)

閱讀本文的目的?

以前有小夥伴反應 kotlin lambda與高階函數 仍是有點雲裏霧裏的,因此特地再補上一篇,學完這篇,相信你就真正的瞭解了kotlin中lambda與高階函數的 本質了,也再也不懼怕使用了。java

java中函數能做爲參數傳遞嗎?

在java中 是不容許 將函數做爲參數傳遞的。 這個相信多數java開發者都知道。可是java是開了一個相似的口子的。 就是回調函數。 回調函數的目的 其實就是將函數 做爲一個參數傳遞到另一個函數中。jvm

相似下面的代碼: 函數

其實咱們傳遞進去的雖然表面看起來是一個對象,可是咱們使用的倒是這個對象中的 方法。post

因此實際上這樣設計的意圖就是將一個函數傳遞到另一個函數裏面。設計

語法上雖然java 是不支持將函數 做爲參數 傳遞的,可是實際用起來java 給咱們留了一個相似的後門。 就是回調函數了。 可是咱們要知道 他這個後門也是創建在實際傳對象進去的基礎上的。3d

kotlin中的函數能夠做爲參數傳遞嗎?

答案是能夠的。可是大家要知道 kotlin的這種特性其實也是一種語法糖,他並不能突破jvm的限制,也就是說jvm不支持函數做爲參數傳遞,那麼kotlin也是不支持的,可是kotlin 能夠經過語法糖的方式,讓kotlin的開發者能夠認爲 kotlin中能夠將函數做爲參數傳遞cdn

咱們來舉個例子:對象

看完上面的例子 咱們得出一個結論,kotlin中 函數雖然不是一種類型, 可是咱們卻能夠根據函數的參數和函數的返回值 來抽象出一種定義函數的方式。 就是圖中我紅色的註釋。blog

既然有了這個基礎,那麼在kotlin中 咱們就能夠將函數做爲一個參數傳遞進去了。事件

既然函數a 咱們定義成了一個高階函數,能夠接受一個函數 做爲參數 來調用,那咱們就看看是如何使用他吧。

到這裏咱們應該得出一個結論: Kotlin中的 函數做爲參數傳遞的時候 其實本質上傳遞的是一個對象。

那既然 傳遞的是一個對象, 也能夠支持傳遞匿名對象的吧?其實也是能夠的:

kotlin中的lambda 與匿名函數的關係

其實這倆就是對等的關係, 有了上面的基礎 我再寫幾個例子 大家就明白了。

這個函數 你們再熟悉不過了吧,給一個view 添加一個點擊事件。

本質上 咱們能夠看到 其實這個setOnclickListener函數但願獲得的 是一個 參數爲view 返回值爲 void 的函數。

因此 咱們能夠這麼寫:

沒毛病吧?咱們給他一個 匿名的函數類型的對象 參數是view類型的,返回值是Unit 這個寫法 若是上面的內容 你能看懂的話 看到這裏 應該是沒壓力的。

而後咱們就能夠用lambda 來簡化咱們的寫法:

v:View 表明這個匿名函數的參數類型, 而後lambda中最後一行 就表明返回值了。

由於咱們這個參數類型是一個沒有返回值的 函數類型,因此這裏println函數沒有返回值 也沒問題。

還能夠更加簡寫一下:

你看這個寫法 參數聲明也省略掉了。

lambda 做爲一個聲明語句的一部分

最後咱們再寫一段代碼 強化理解一下kotlin中 高階函數與lambda的關係。

首先

咱們聲明瞭一個函數類型的對象。 他是匿名的。 咱們想到 匿名函數不是能夠用lambda 來簡化嗎?

而且lambda 中最後一行固定就是這個匿名函數的返回值啊

因而咱們想這樣簡寫:

你看這裏報錯了,這是爲啥? 其實很簡單,這裏編譯器沒法知道 你這個lambda 也就是匿名函數的參數是什麼類型

你都沒有聲明參數的類型,你怎麼能直接使用他呢? 那不是確定報錯嗎?

因此咱們在聲明的地方標定一下 這個函數的類型(參數和返回值) 不就可使用好lambda的簡寫了嗎?

相關文章
相關標籤/搜索