1. 程式人生 > >Lambda表示式,匿名函式,高階函式——Kotlin

Lambda表示式,匿名函式,高階函式——Kotlin

高階函式 高階函式可以將函式作為引數,或者可以返回一個函式作為返回值。

這有一個關於集合的例子,有兩個引數,初始累積值和組合函式,通過將當前累積值和每個集合元素組合,替換累積值。 在這裡插入圖片描述 上面的程式碼中,引數combine的函式型別是*(R, T) -> R*,那麼它的兩個引數型別是RT,返回值型別是Rcombine是通過在for-loop裡面觸發的,combine的返回值賦值給accumulator。 為了呼叫fold,我們需要傳入一個函式型別的引數,lambda表示式作為引數廣泛應用於高階函式呼叫中。 在這裡插入圖片描述 再舉一個例子(這個例子不是原文中的,出處已經找不到了)。函式compose的兩個引數都是函式型別,並且返回值也是函式型別。compose

和我們數學概念上的函式更加接近f(g(x))。 在這裡插入圖片描述

Lambda表示式和匿名函式

Lambda表示式和匿名函式是“字面函式(function literals)”,也就是函式沒有被申明,但可以立即作為表示式傳遞。看下面這個例子: 在這裡插入圖片描述 函式max是一個高階函式,第二個引數是一個函式,並且第二個引數是一個表示式,這個表示式自身就是一個函式,也就是這個函式在字面上等價於下面這個函式 在這裡插入圖片描述 Lambda表示式句法 Lambda表示式的完整句法形式如下: 在這裡插入圖片描述 Lambda表示式總是被大括號括起來,在完整句法形式下,引數的申明在大括號裡,型別註釋可選,函式體在符號 ->後面。如果Lambda表示式的推斷的返回型別不是Unit,在Lambda表示式中最後(或者可能只有一行)的表示式被作為返回值。

如果我們移除所有的型別註釋,就變成下面這個樣子了: 在這裡插入圖片描述

傳遞Lambda表示式給最後一個引數

Kotlin有一個規範,如果一個函式接收一個函式作為最後一個引數,作為引數傳遞的Lambda表示式可以放在括號外: 在這裡插入圖片描述 如果Lambda表示式是唯一的引數,括號可以完全省略: 在這裡插入圖片描述 it: 一個引數的隱式名稱。

僅有一個引數的Lambda表示式是非常常見的。

如果編譯器自己能夠找出簽名,唯一的引數就可以不用申明並且省略掉->。該引數將隱式的以it命名: 在這裡插入圖片描述

從Lambda表示式返回一個值

我們可以顯示地使用return從Lambda返回一個值,另外最後一個表示式的值隱式地作為返回值。 在這裡插入圖片描述

匿名函式

上面介紹的Lambda表示式語法中缺少了對指定返回型別的介紹。大部分情況下,這是沒有必要的,因為返回型別可以自動推斷出來。如果你需要顯示的指明,你可以使用另一個句法:匿名函式 在這裡插入圖片描述

匿名函式非常像常規函式的申明,只是沒有名字。函式體可以是表示式(像上面)或者塊: 在這裡插入圖片描述 引數和返回型別和常規函式的申明方式是一樣的,但是如果引數型別可以通過上下文推斷出來,那麼可以省略: 在這裡插入圖片描述 匿名函式返回型別的推斷和正常函式是一致的,對於具有表示式的匿名函式的返回值型別是自動推斷的,對於具有塊的匿名函式,返回型別需要顯示地指定。

需要注意的是,匿名函式的引數總是在括號裡傳遞。允許將函式放在括號外的簡寫語法僅適用於Lambda表示式。

Lambda表示式和匿名函式的另一個不同點是*non-local return的行為。沒有標籤的返回語句總是從帶有fun*關鍵字申明的函式返回。這意味著Lambda表示式中的返回值將從閉函式返回,而匿名函式中的返回值將從匿名函式本身返回(可以參考non-local return的解釋https://kotlinlang.org/docs/reference/inline-functions.html#non-local-returns)。