以前有小夥伴反應 kotlin lambda與高階函數 仍是有點雲裏霧裏的,因此特地再補上一篇,學完這篇,相信你就真正的瞭解了kotlin中lambda與高階函數的 本質了,也再也不懼怕使用了。java
在java中 是不容許 將函數做爲參數傳遞的。 這個相信多數java開發者都知道。可是java是開了一個相似的口子的。 就是回調函數。 回調函數的目的 其實就是將函數 做爲一個參數傳遞到另一個函數中。jvm
相似下面的代碼: 函數
其實咱們傳遞進去的雖然表面看起來是一個對象,可是咱們使用的倒是這個對象中的 方法。post
因此實際上這樣設計的意圖就是將一個函數傳遞到另一個函數裏面。設計
語法上雖然java 是不支持將函數 做爲參數 傳遞的,可是實際用起來java 給咱們留了一個相似的後門。 就是回調函數了。 可是咱們要知道 他這個後門也是創建在實際傳對象進去的基礎上的。3d
答案是能夠的。可是大家要知道 kotlin的這種特性其實也是一種語法糖,他並不能突破jvm的限制,也就是說jvm不支持函數做爲參數傳遞,那麼kotlin也是不支持的,可是kotlin 能夠經過語法糖的方式,讓kotlin的開發者能夠認爲 kotlin中能夠將函數做爲參數傳遞。cdn
咱們來舉個例子:對象
看完上面的例子 咱們得出一個結論,kotlin中 函數雖然不是一種類型, 可是咱們卻能夠根據函數的參數和函數的返回值 來抽象出一種定義函數的方式。 就是圖中我紅色的註釋。blog
既然有了這個基礎,那麼在kotlin中 咱們就能夠將函數做爲一個參數傳遞進去了。事件
既然函數a 咱們定義成了一個高階函數,能夠接受一個函數 做爲參數 來調用,那咱們就看看是如何使用他吧。
到這裏咱們應該得出一個結論: Kotlin中的 函數做爲參數傳遞的時候 其實本質上傳遞的是一個對象。
那既然 傳遞的是一個對象, 也能夠支持傳遞匿名對象的吧?其實也是能夠的:
其實這倆就是對等的關係, 有了上面的基礎 我再寫幾個例子 大家就明白了。
這個函數 你們再熟悉不過了吧,給一個view 添加一個點擊事件。
本質上 咱們能夠看到 其實這個setOnclickListener函數但願獲得的 是一個 參數爲view 返回值爲 void 的函數。
因此 咱們能夠這麼寫:
沒毛病吧?咱們給他一個 匿名的函數類型的對象 參數是view類型的,返回值是Unit 這個寫法 若是上面的內容 你能看懂的話 看到這裏 應該是沒壓力的。
而後咱們就能夠用lambda 來簡化咱們的寫法:
v:View 表明這個匿名函數的參數類型, 而後lambda中最後一行 就表明返回值了。
由於咱們這個參數類型是一個沒有返回值的 函數類型,因此這裏println函數沒有返回值 也沒問題。
還能夠更加簡寫一下:
你看這個寫法 參數聲明也省略掉了。
最後咱們再寫一段代碼 強化理解一下kotlin中 高階函數與lambda的關係。
首先
咱們聲明瞭一個函數類型的對象。 他是匿名的。 咱們想到 匿名函數不是能夠用lambda 來簡化嗎?
而且lambda 中最後一行固定就是這個匿名函數的返回值啊
因而咱們想這樣簡寫:
你看這裏報錯了,這是爲啥? 其實很簡單,這裏編譯器沒法知道 你這個lambda 也就是匿名函數的參數是什麼類型
你都沒有聲明參數的類型,你怎麼能直接使用他呢? 那不是確定報錯嗎?
因此咱們在聲明的地方標定一下 這個函數的類型(參數和返回值) 不就可使用好lambda的簡寫了嗎?