kotlin 函數提高篇之高階函數與 lambda
文章目錄
- kotlin 函數提高篇之高階函數與 lambda
-
- 正文
-
-
- 1. 一個例子看高階函數
- 2. 函數類型
- 3. invoke 調用函數
- 4. 閉包
- 5. 使用下劃線表示未使用的變量
- 6. 内聯函數
-
正文
- 高階函數就是将函數作為參數或傳回值的函數。
1. 一個例子看高階函數
//[1] 函數擴充, 給集合擴充一個 myfold 方法, 用作集合的累計器
//比較像政策模式,定義一個政策,實作方實作具體政策
fun <T, R> Collection<T>.myfold(
initial: R,
combine: (acc: R, nextElement: T) -> R
): R {
var accumulator: R = initial
for (element: T in this) {
println("myfold ::執行前 $accumulator")
accumulator = combine(accumulator, element)
println("myfold :: acc = $accumulator, i = $element")
}
return accumulator
}
fun main() {
val items = listOf(1, 2, 3, 4, 5)
var myfold = items.myfold(initial = 0,
// [2] Lambda 表達式就是花括号擴起來的代碼塊
combine = {
//[3]? 如果一個 lambda 有參數,前面參數,後面跟 '->', 箭頭後面的都是 lambda 表達式
acc: Int, nextElement: Int ->
println("main::acc = $acc, i = $nextElement")
val result = acc + nextElement
println("main::result = $result")
// [4] lambda 表達式最後一個就是傳回值
result
})
println("$myfold")
}
2. 函數類型
4個概念記一記
//[1] kotlin 使用類似 (Int) -> String 來聲明函數
val onClick:() -> Unit = {}
//[2] 下面表示接受 A 與 B 兩個參數,并傳回 C 類型值的函數類型
(A, B)-> C
val sum:(Int, Int) -> Int = {x:Int, y:Int -> x + y}
//[3] 帶接受者的函數,如下。
A.(B) -> C
//[4] 挂起函數,有 suspend 修飾符
suspend A.(B) -> C
3. invoke 調用函數
//[1] 使用 invode 來進行函數變量的函數調用
val add:(String , String) -> String = {a, b -> a + b}
println(add("s", "s"))
println(add.invoke("s2", "s2"))
4. 閉包
- kotlin 一個不成文的約定,如果函數最後一個參數是函數,那麼相應參數傳入的 lambda 表達式可以放在圓括号外
- 如果該 lambda 表達式是調用唯一參數,那麼圓括号也可以省略
//[1] 是否帶函數參數的函數,有點繞哈
bibao1(1 ,{b ->
1
})
//[2] 編譯器會提示,因為最後個參數是函數參數你觸發了閉包條件,可以使用閉包
bibao1(1) { b ->
1
}
//[3] 這個樣子,就觸發不了閉包條件
bibao2(1 ,{b ->
1
}, 2)
//[4] 因為沒使用參數,再次提示隐藏參數
bibao1(1) {
1
}
5. 使用下劃線表示未使用的變量
//[1] 第一個參數未使用,但是第二個使用了,導緻不能省略,但是可以略寫啊
map.forEach { _, value -> println("$value!") }
6. 内聯函數
- 使用高階函數會有運作時的效率損失,因為對函數對象的記憶體配置設定和虛拟調用會引入時間開銷
- inline 修飾符會影響函數本身和傳給它的 lambda 表達式,将所有這些都内聯到調用處