您好,登錄后才能下訂單哦!
詳解Kotlin 高階函數 與 Lambda 表達式
高階函數(higher-order function)是一種特殊的函數, 它接受函數作為參數, 或者返回一個函數. 這種函數的一個很好的例子就是 lock() 函數, 它的參數是一個鎖對象(lock object), 以及另一個函數, 它首先獲取鎖, 運行對象函數, 然后再釋放鎖:
fun <T> lock(lock: Lock, body: () -> T): T { lock.lock() try { return body() }finally { lock.unlock() } }
上面的代碼: body 參數是一個 函數類型: () -> T , 因此它應該是一個函數, 這個函數沒有參數, 返回一個 T 類型的值。
高階函數類似 C 語言的函數指針,高階函數另一個例子:
fun <T, R> List<T>.map(transform: (T) -> R): List<R> { val result = arrayListOf<R>() for (item in this) result.add(transform(item)) return result } val doubled = ints.map { it -> it * 2 } // 調用
函數類型(Function Type)
對于接受另一個函數作為自己參數的函數, 我們必須針對這個參數指定一個函數類型, 例如前面例子的 map 函數,參數 transform 的類型是 (T) -> R, 意思是它是一個函數,參數 T, 返回 R。
引用以及返回一個函數
高階函數可以接受函數參數,也可以返回一個函數引用, 函數可以賦值給變量,和 C 語言的函數指針一樣。
fun bar(): (String) -> String = { str -> str.reversed() } val reversi = bar() reversi("hello") reversi("world")
內聯函數(Inline Function)
Kotlin 支持內聯函數,函數內聯也許會導致編譯產生的代碼尺寸變大, 但如果我們使用合理(不要內聯太大的函數), 可以換來性能的提高。
inline fun foo() { // }
如果一個內聯函數的參數中有多個 Lambda 表達式, 而你只希望內聯其中的一部分, 你可以對函數的一部分參數添加 noinline 標記。
inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) { // ... }
Lambda 表達式
Lambda 表達式的完整語法形式,如:
val sum = { x: Int, y: Int -> x + y }
Lambda 表達式包含在大括號之內, 在完整語法形式中, 參數聲明在圓括號之內, 參數類型的聲明可選, 函數體在 -> 符號之后. 如果 Lambda 表達式自動推斷的返回值類型不是 Unit , 那么 Lambda 表達式函數體中, 最后一條(或者就是唯一一條)表達式的值, 會被當作整個 Lambda 表達式的返回值。
很多情況下 Lambda 表達式只有唯一一個參數. 如果 Kotlin 能夠自行判斷出 Lambda 表達式的參數定義,那么它將允許我們省略唯一一個參數的定義, 并且會為我們隱含地定義這個參數, 使用的參數名為 it :
ints.filter { it > 0 }
使用 帶標簽限定的 return 語法, 我們可以在 Lambda 表達式內明確地返回一個結果值. 否則, 會隱含地返回 Lambda 表達式內最后一條表達式的值。
ints.filter { val shouldFilter = it > 0 return@filter shouldFilter }
匿名函數(Anonymous Function)
匿名函數看起來與通常的函數聲明很類似, 區別在于省略了函數名。
fun(x: Int, y: Int): Int = x + y
參數和返回值類型的聲明與通常的函數一樣, 但如果參數類型可以通過上下文推斷得到, 那么類型聲明可以省略:
ints.filter(fun(item) = item > 0)
閉包
所謂閉包,就是一個代碼塊可以訪問外層作用域的變量和參數,例如上面提到的 Lambda 表達式和匿名函數。
var containsNegative = false val ints = listOf(0, 1, 2, 3, 4, 5) ints.forEach { if (it < 0) containsNegative = true }
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。