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