一文弄懂 kotlin lambda與高階函式

DK_BurNIng發表於2020-04-05

閱讀本文能解決什麼問題

我發現很多學過kotlin的人,遲遲不敢在專案中運用,主要是因為kotlin的 lambda與高階函式沒有學好。這2個東西往往是一起運用的。 網上很多類似的文章都講的不夠通透,導致大部分人都卡在這裡。或者有一些人即使寫了kotlin 但是也沒用好lambda與高階函式,導致kotlin的程式碼 全是java的味道。

大家可以用一下新版本的android studio,然後新建一個kotlin語言的loginActivity,如果裡面的程式碼你能無障礙的基本看懂,那這篇文章就不用再看了,如果看起來障礙很大,那麼建議你仔細看完這篇文章,之後再返回去看這個loginActivity的程式碼,相信結果是完全不一樣的。

最後總結一下我的觀點:想寫好Kotlin的程式碼就看你對lambda與高階函式理解的有多深,早期糾結那些晦澀的語法糖沒有任何意義

到底啥是匿名函式

一文弄懂 kotlin lambda與高階函式

那這個func 又怎麼理解呢?他為啥可以接受一個函式作為引數?

一文弄懂 kotlin lambda與高階函式

一文弄懂 kotlin lambda與高階函式

這裡有人會問了,你咋知道 這個匿名函式是沒有返回值的啊?

因為lambda表示式有一個特點,lambda括號裡面的函式最後一行就是這個函式的返回值, 圖中我們最後一行 是個print語句,這個print函式顯然是沒有返回值的,所以這個lambda 也就是這個匿名函式也就沒有了返回值了。

帶引數的lambda

一文弄懂 kotlin lambda與高階函式

然後我們反編譯看一下這段程式碼

一文弄懂 kotlin lambda與高階函式

我們換個寫法

一文弄懂 kotlin lambda與高階函式

我們再看一下反編譯的:

一文弄懂 kotlin lambda與高階函式

下面我們再改進一下寫法:

一文弄懂 kotlin lambda與高階函式

那當然還有終極的簡寫,也就是平常我們使用最多的寫法:

一文弄懂 kotlin lambda與高階函式

很多人學不好lambda就是因為上來就看這個最簡單的寫法,而不知道這種寫法是怎麼來的。你搞清楚 這種寫法的進化原因,自然就真正理解了lambda了。

一文弄懂 kotlin lambda與高階函式

來個更進一步 2個引數的

一文弄懂 kotlin lambda與高階函式

看下執行結果

一文弄懂 kotlin lambda與高階函式

一文弄懂 kotlin lambda與高階函式

一文弄懂 kotlin lambda與高階函式

實際上kotlin中的lambda 就是一個匿名函式,java8的lambda表示式 卻是一個sam的語法糖

高階函式

有了前面lambda 的鋪墊,高階函式 的理解就不難了。 下面給高階函式下一個定義: 引數型別包含函式型別,或者返回值型別是一個函式型別 的函式 都可以稱之為是高階函式。

來看幾個簡單的高階函式的例子:

一文弄懂 kotlin lambda與高階函式

看下原始碼:

一文弄懂 kotlin lambda與高階函式

再看個函式

一文弄懂 kotlin lambda與高階函式

然後我們看一下map函式的定義

一文弄懂 kotlin lambda與高階函式

所以你看高階函式 也沒什麼難的,主要你能理解lambda 那麼你就能理解好高階函式

谷歌原始碼裡最常用的幾個高階函式

無非就是let run also apply use 這麼5個,網上關於這幾個函式的資料很多,但是介紹的我覺得都相當一般,這裡我重新介紹一下 這幾個函式對應的使用場景。 掌握了他們,可以說 理解kotlin的程式碼 就不會存在什麼障礙了。

這裡要著重說明的是,其實run函式和apply函式 並沒啥大作用。平時自己寫 主要還是let also 和use

看一段程式碼,看看let和also的區別

一文弄懂 kotlin lambda與高階函式

最後一個use操作符,是個人最愛的一個操作符,因為這東西真的省事。我演示一遍你就知道他有多省事了!

一文弄懂 kotlin lambda與高階函式

最後用一張圖來總結:

一文弄懂 kotlin lambda與高階函式

高階函式-集合的變換

我們平時開發業務程式碼時 其實最主要的工作就是對一個集合進行增刪改查,過濾啊 之類的操作。 kotlin中 提供了大量對集合操作的 高階函式,理解好他們 對你讀程式碼或者是寫程式碼的操作都是非常非常有幫助的。

前面的程式碼中我們已經演示過了for each迴圈的用法 這裡補充一點,foreach函式是可以提前跳出的。

一文弄懂 kotlin lambda與高階函式

當然上面的寫法一般是不推薦的,因為確實很迷惑人。 有更高階的函式 可以滿足你對集合的要求。

看下圖:

一文弄懂 kotlin lambda與高階函式

看個例子:

一文弄懂 kotlin lambda與高階函式

有時候我們對一個集合的操作,可能不止一個函式,需要多個函式協同操作,這個時候有更方便的 寫法。

一文弄懂 kotlin lambda與高階函式

有人要問了,這個asSeq不呼叫 是啥效果?我們可以看一下

一文弄懂 kotlin lambda與高階函式

一文弄懂 kotlin lambda與高階函式

再看一個例子

一文弄懂 kotlin lambda與高階函式

看下flatmap

一文弄懂 kotlin lambda與高階函式

集合的聚合操作

先看一張圖 瞭解一下主要的聚合操作

一文弄懂 kotlin lambda與高階函式

看下fold的使用

一文弄懂 kotlin lambda與高階函式

一文弄懂 kotlin lambda與高階函式

其餘的2個高階函式就不再演示了。大家用到的時候自行查閱api即可。

試試高階函式和lambda 怎麼組合使用 解決問題?

前面已經學完了lambda和大部分高階函式,這裡我們組合一下他們的用法,重新將知識串起來。

1.統計一個檔案裡 除了空格字元以外,每個字元出現的次數(儘量只使用lambda)

/**
 *  1.讀檔案 然後把檔案的內容 轉成char的陣列
 *  2.過濾陣列,空格符直接忽略
 *  3.用groupBy 來將整個陣列 重新分組(分組的結果是一個map), key就是出現的字元,value就是出現的全部字元
 *  4.用map操作符 再將這個map 拍平成一個list,這個list的 內容形如:e 出現次數: 21
 *  5.用let操作符 將結果列印出來即可
 */
fun main() {

    File("/Users/wuyue/IdeaProjects/KotlinTest/src/enumTest.kt").readText().toCharArray().filterNot {
        it.isWhitespace()
    }.groupBy {
        it
    }.map {
        it.key + " 出現次數: " + it.value.size
    }.let {
        println(it)
    }
}

複製程式碼

相關文章