<font face= 黑體>在 Kotlin 學習筆記以內置類型(2)中咱們已經將 Kotlin 函數的基本概念和基本用法講完了,今天咱們來說函數進階。java
<font face= 黑體>高階函數就是參數類型包含函數類型或者返回值類型是函數類型的函數,簡單的說,高階函數就是函數裏面套函數,以下所示:git
// 參數類型是函數類型 fun needsFunction(block: () -> Unit) { block() } // 返回值是函數類型 fun returnsFunction(): () -> Long { return {System.currentTimeMillis()} }
<font face= 黑體>forEach 函數: 接受的參數是一個函數github
// Kotin 自帶的 forEach 函數 inline fun IntArray.forEach(action: (Int) -> Unit): Unit { for (element in this) action(element) }
<font face= 黑體>map 函數: 接受的參數是一個函數segmentfault
// Kotin 自帶的 map 函數 inline fun <R> IntArray.map(transform: (Int) -> R): List<R> { return mapTo(ArrayList<R>(size), transform) }
<font face= 黑體>forEach 的調用:數組
val intArray = IntArray(5){ it + 1 } intArray.forEach(::println) // 括號() 裏面其實能夠把它當作一個參數,只是這個參數是函數 intArray.forEach ({ println(it) }) // () 能夠省略,就變成了下面這樣 intArray.forEach { println(it) }
<font face= 黑體>forEach 接受的類型參數類型是 (Int) -> Unit,而 println 函數的類型有一個就是 (Int) -> Unit,因此能夠用函數引用來接收。
<font face= 黑體>被 inline 標記的函數就是內聯函數,其原理就是:在編譯時期,把調用這個函數的地方用這個函數的方法體進行替換。咱們來看下面這個代碼,就是一個 forEach 函數遍歷數組:性能優化
val ints = intArrayOf(1, 2, 3, 4) ints.forEach { println("Hello $it") }
<font face= 黑體>forEach 函數的定義上面咱們已經看到了,以下,能夠看到,forEach 被 inline 修飾,因此它是個內聯函數函數
inline fun IntArray.forEach(action: (Int) -> Unit): Unit { for (element in this) action(element) }
<font face= 黑體>其實 forEach 真正的實現是下面這個代碼:性能
for (element in this) action(element)
<font face= 黑體>內聯函數能夠減小函數的調用來優化性能。學習
<font face= 黑體>內聯函數的定義很簡單,就是在一個函數的前面加上 inline 關鍵字。優化
inline fun hello() { println("hello") }
<font face= 黑體>雖說內聯函數能夠減小函數的調用來優化性能,可是並非每一個函數前加一個 inline 就能夠優化性能,其實咱們通常會把高階函數定義爲內聯函數。
cost { println("hello") }
inline fun cost(block: () -> Unit) { val start = System.currentTimeMillis() block() println(System.currentTimeMillis() - start) }
<font face= 黑體>好比說咱們要計算 println("hello") 這段代碼執行的時間,若是不加 inline 的話,那麼調用 cost 就要建立 Lambda 表達式,函數調用,結果發現這些操做的時間就要大於 println("hello") 這段代碼執行的時間,這樣是徹底沒有必要的,因此咱們加上 inline 以後,調用 println("hello"),實際上就等於下面這樣:
val start = System.currentTimeMillis() println("hello") println(System.currentTimeMillis() - start)
<font face= 黑體>能夠看到加上 inline 以後,cost 函數的調用開銷沒了,Lambda 表達式的建立開銷也沒了,這就是內聯函數的做用。
<font face= 黑體> 其實內聯函數最重要的是對高階函數的性能優化。
<font face= 黑體>本篇博客主要講了 Kotlin 中的高階函數和內聯函數,下一節咱們講 Kotin 的 集合變換與聚合。
源碼 已上傳至 github,有須要能夠直接下載。