1. 程式人生 > 實用技巧 > kotlin函式和Lambda表示式——>高階函式與lambda表示式

kotlin函式和Lambda表示式——>高階函式與lambda表示式

1.高階函式

  高階函式是將函式用作引數或返回值的函式。

  一個不錯的示例是集合的函式式⻛格的 fold,它接受一個初始累積值與一個接合函式,並通過將當前 累積值與每個集合元素連續接合起來代入累積值來構建返回值:

fun <T, R> Collection<T>.fold(
        initial: R,
        combine: (acc: R, nextElement: T) -> R
): R {
    var accumulator: R = initial
    for (element: T in this) {
        accumulator 
= combine(accumulator, element) } return accumulator } //在上述程式碼中,引數combine 具有函式型別 (R, T) -> R ,因此 fold 接受一個函式作為引數,該函式接受型別分別為 R 與 T 的兩個引數並返回一個 R 型別的值。 // 在 for-迴圈內部呼叫該函式,然後 將其返回值賦值給 accumulator 。

  為了呼叫 fold,需要傳給它一個函式型別的例項作為引數,而在高階函式呼叫處,(下文詳述 的)lambda 表達 式廣泛用於此目的。

val items = listOf(1, 2, 3, 4
, 5) // Lambdas 表示式是花括號括起來的程式碼塊。 items.fold(0, { // 如果一個 lambda 表示式有引數,前面是引數,後跟“->” acc: Int, i: Int -> print("acc = $acc, i = $i, ") val result = acc + i println("result = $result") // lambda 表示式中的最後一個表示式是返回值: result }) // lambda 表示式的引數型別是可選的,如果能夠推斷出來的話: val joinedToString = items.fold("
Elements:", { acc, i -> acc + " " + i }) // 函式引用也可以用於高階函式呼叫: val product = items.fold(1, Int::times)

2.函式型別

  Kotlin 使用類似 (Int) -> String 的一系列函式型別來處理函式的宣告:val onClick: () - > Unit = ......。

//這些型別具有與函式簽名相對應的特殊表示法,即它們的引數和返回值:
//— 所有函式型別都有一個圓括號括起來的引數型別列表以及一個返回型別:(A, B) -> C 表示接受 型別分別為 A 與 B 兩個引數並返回一個 C 型別值的函式型別。引數型別列表可以為空,如 () - > A。Unit返回型別不可省略。
//— 函式型別可以有一個額外的接收者型別,它在表示法中的點之前指定:型別 A.(B) -> C 表示可 以在 A 的接收者物件上以一個 B 型別引數來呼叫並返回一個 C 型別值的函式。帶有接收者的函 數字面值通常與這些型別一起使用。
//— 掛起函式屬於特殊種類的函式型別,它的表示法中有一個 suspend 修飾符 ,例如 suspend () - > Unit 或者 suspend A.(B) -> C 。

  函式型別表示法可以選擇性地包含函式的引數名:(x: Int, y: Int) -> Point 。這些名稱可用於表明引數的含義。

//如需將函式型別指定為可空,請使用圓括號:((Int, Int) -> Int)?。
//函式型別可以使用圓括號進行接合:(Int) -> ((Int) -> Unit)
//箭頭表示法是右結合的,(Int) -> (Int) -> Unit 與前述示例等價,但不等於 ((Int) -> (Int)) -> Unit。

  還可以通過使用類型別名給函式型別起一個別稱:

typealias ClickHandler = (Button, ClickEvent) -> Unit

3.函式型別例項化

  有幾種方法可以獲得函式型別的例項: