Kotlin的高階函數和常用高階函數


Kotlin的高階函數和常用高階函數

高階函數的定義

將函數當做參數或者是返回值的函數

什么是高階函數

可以看看我們常用的 函數:

首先我們可以知道, 是 的擴展函數,然后參數是 ,但是 不再像和我們以前Java那樣傳遞的是一個對象,這時傳遞的是一個函數。這個函數的入參為 ,返回值為 。所以 也是一個高階函數,因為它將函數當做參數進行傳遞了。我們嘗試着去調用一下 函數:

調用的時候,我們將 函數傳遞給了 函數,這里采用的是函數引用。就上訴代碼,我們還可以結合 表達式來進行處理:

其實以上幾種的方式得到的結果都是一樣的,但是第一種就是簡潔了許多。

我們再定義一個類,用來打印 的值:

根據函數引用的特性,我們可以這樣調用 函數:。由於 中的 函數的入參類型是 類型,也就是任意類型,不管 傳遞的是什么值都可以接收。那現在我們再將其作為 的參數傳遞進去:

編譯器告訴我們這個是錯誤的。那我們來分析一下吧:我們再定義一個 類

然后進行以下操作:

可以看到 分別對 和 的解釋:

是一個方法,然后參數類型為 ,返回值為

也是一個方法,但是參數有兩個,分別是 和 類型, 返回值為

在 中,只有一個參數傳遞,但是 需要的是兩個參數,肯定就會報錯,所以我們需要對此進行修改:

這個樣子就OK了。

常用高階函數

map:變換

通常我們會使用以下的方式來實現對集合中的元素進行修改的操作:

如果采用這種方式,遠遠不能體現Kotlin的優勢了,這個和Java有什么區別呢?「狗子,上map」:

從打印結果可以看到他們的實現效果是一模一樣的,這個就是 的功能,可以對集合中的元素進行你想要的操作,是不是跟 的 很類似呢!我們來細看一下 的實現原理:

方法中主要做的就是調用 方法,然后傳遞的是新創建並且初始長度為10的 和 函數,在 方法中,對集合進行迭代,然后將進行變換后的數據添加到新的集合中,最后返回新的集合。

操作不僅可以將元素變換成與之前類型相同的元素,也可以變化成與之前元素類型不同的元素,具體你想變換成什么類型,這個是不做限制的。

flatMap:變換

看起來跟 很相似,其實真的很類似,搞得有時候自己都不知道應該使用哪個操作符了,那就從源碼來看看它們之間的區別吧。

可以看到 中的參數 是一個返回值為 的函數,而 的參數 是一個返回值為 的函數。然后調用 方法,將 和一個新創建的 傳遞給了 方法。在 方法中,對當前的集合進行了迭代,然后將執行過變換操作后的集合數據全部添加到新的集合中,最終返回新的集合。

和 的主要區別就是在於傳入的函數的返回值,一個是任意對象,一個是實現了 接口的對象

reduce

例子:打印集合中的元素之和

還是直接對源碼進行分析吧,感覺看了源碼就一目了然了。

首先對當前的集合進行判空處理,接着將第一個元素賦值給 , 的類型是 。然后對當前集合進行迭代處理,並調用我們傳遞進去的參數 , 函數中傳遞了兩個參數,一個是 類型的,一個是集合元素類型的。 函數的返回值也是 類型的,將 的返回值重新賦值給 。迭代完畢以后返回我們的 。

其實通過我們解讀源碼以后,我們就可以知道 函數會將上一次的計算結果傳遞到下一次計算中,我們可以利用這個方式來實現以下字符串拼接,當然我們的字符串拼接有其他更好的方式,這里只是做為講解 的例子而已:

fold:能夠添加初始值的reduce

不得不說, 跟 的作用基本是一致的,只是 能夠添加初始值,什么叫做能夠添加初始值呢?讓我們來舉個栗子看看唄!

還是看源碼吧:

看着源碼就會覺得這些函數的操作很是簡單了。 函數還有很多的兄弟:

說的再多也不如看結果

這個函數就是多了一個 的參數,具體的用處暫時沒有發現,就不做數據打印了。

filter:過濾

例子:過濾集合中的奇數

上源碼:

在 中創建新的集合 ,將 和 函數一並傳遞給 函數。在 函數中,先對當前的集合進行遍歷,如果滿足條件 就將當前的元素添加到新的集合中, 就是我們傳遞進來的那個函數,返回值是一個 類型的。

takeWhile:截取集合中的數據,直到第一個不滿足條件的元素為止

例子:截取集合中不能夠被5整除的數,直到第一個不滿足條件的元素為止。

源碼:

let:將調用者當做參數傳遞給指定的函數

例子:省略if空判斷

源碼:

源碼也是很簡單,就是將調用者傳遞給傳入進來的函數並執行傳入進來的函數。

apply:執行指定函數,並且返回調用者

例子:修改person類的age屬性

上訴的例子真的只是例子,它沒有跟你講 有多強大,它只是描述了的作用。源碼:

就是單純的執行函數 並返回調用者。

with

例子:文件讀取

源碼:

接收兩個參數,一個是 ,上訴例子中就是 ,另一個就是 ,在上訴例子中,我們使用了 表達式,所以這個函數就移到了括號外面了。

疑惑點

函數定義中 `T.() -> Unit` 和 `() -> Unit` 的區別

我們一般定義函數都會選擇定義

上訴代碼表示: 的擴展方法 接收一個 的函數,該函數是無參無返回的。

那我們再見識見識 這種方式定義的方法,其實也很多見了:

可以看到 函數使用的是 這種方式,他們兩到底有啥區別呢?

我在 定義了兩個方法:

分別使用 調用這兩個方法試試:

從圖片中可以看出 : 中的 對象指的是調用對象 ,也就是 ,而 沒有提示,那么我們就看打印吧:

原來 方法中的 對象指的是外部對象,在這里就是我們的 對象。

總結

這兩個函數唯一的區別就是 與 的區別,我們調用時,在代碼塊里面寫this,的時候,根據代碼提示,我們可以看到,連個this代表的含義不一樣, 里的this代表的是自身實例,而 里,this代表的是外部類的實例

感謝

[Kotlin中,函數作為參數,T.()->Unit 和 ()->Unit 的區別][https://www.jianshu.com/p/88a656e59c61]

This is All


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM