高階函數(shù)指以另一個(gè)函數(shù)或 lambda 表達(dá)式為參數(shù)或返回值類型的函數(shù)
調(diào)用時(shí)與調(diào)用普通函數(shù)一樣。
fun main(args: Array<String>) {
test { println("aaa${it}") }
}
// 聲明 a 為函數(shù)類型
fun test(a:(Int)->Unit){
a(11) // 調(diào)用 a 函數(shù)
}
作為返回值
需要指定函數(shù)類型作為返回值類型。下例中 test 函數(shù)聲明了一個(gè)函數(shù)類型做為返回值 —— 該函數(shù)接收 Int 類型參數(shù),并返回 String。因此 test(1) 后可以直接使用 () 調(diào)用返回的函數(shù)。
fun main(args: Array<String>) {
println(test(1)(222)) // a = 222
println(test(3)(333)) // else
}
fun test(a:Int):(Int)->String{
return when(a){
1-> {a:Int->"a = ${a}"}
else->{b:Int->"else"}
}
}
內(nèi)聯(lián)函數(shù)
使用 inline 修飾的函數(shù)是內(nèi)聯(lián)函數(shù) —— 函數(shù)體會被替換到函數(shù)被調(diào)用的地方,而不是正常的調(diào)用
內(nèi)聯(lián)時(shí),內(nèi)聯(lián)函數(shù)和已知具體內(nèi)容的 lambda 都會被內(nèi)聯(lián)。
函數(shù)的聲明不會被復(fù)制,只復(fù)制函數(shù)的函數(shù)體內(nèi)容。在 java 中也不可能在一個(gè)函數(shù)內(nèi)部定義另一個(gè)函數(shù)。
如下面定義了一個(gè)內(nèi)聯(lián)函數(shù) sync 以及其使用函數(shù) foo:
// 使用 inline 聲明一個(gè)內(nèi)聯(lián)函數(shù)
inline fun <T> synchronized(lock: Lock, action: () -> T): T {
lock.lock()
try {
return action()
}
finally {
lock.unlock()
}
}
// 內(nèi)聯(lián)函數(shù)的使用者
fun foo(l: Lock) {
println("Before sync")
synchronized(l) {
println("Action")
}
println("After sync")
}
其編譯后的代碼如下:

可以發(fā)現(xiàn)將 sync 函數(shù)中的內(nèi)容完全復(fù)制到調(diào)用的地方,包括傳給 sync 的 lambda 表達(dá)式的內(nèi)容也內(nèi)聯(lián)到調(diào)用者中。
說明
在上述代碼中,調(diào)用 sync 時(shí),lambda 表達(dá)式的內(nèi)容是已知的,所以可以將表達(dá)式與 sync 函數(shù)一起被內(nèi)聯(lián)。
但如果調(diào)用內(nèi)聯(lián)函數(shù)時(shí),不知道 lambda 的具體內(nèi)容,則只能內(nèi)聯(lián)內(nèi)聯(lián)函數(shù) —— 即只復(fù)制 sync 函數(shù)的內(nèi)容,無法復(fù)制 lambda 的內(nèi)容。如下,調(diào)用 sync 時(shí)只是復(fù)制了 sync 的代碼,其中 lambda 表達(dá)式的內(nèi)容并沒有復(fù)制,這是因?yàn)樵谡{(diào)用時(shí)無法確定表達(dá)式的具體內(nèi)容:
class LockOwner(val lock: Lock) {
fun runUnderLock(body: () -> Unit) {
synchronized(lock, body)
}
}
class LockOwner(val lock: Lock) {
fun __runUnderLock__(body: () -> Unit) {
lock.lock()
try {
body() // body 是外界傳入的,無法確定內(nèi)容,所以此處不復(fù)制 body 的內(nèi)容
} finally {
lock.unlock()
}
}
}
內(nèi)聯(lián)限制
并不是所有的 lambda 表達(dá)式都可以被內(nèi)聯(lián)。
如果 lambda 表達(dá)式在某個(gè)地方被保存起來,以便后面繼續(xù)使用,表達(dá)式則不能被內(nèi)聯(lián)。同時(shí)會提示
Illegal usage of inline-parameter.。可以使用
noinline修飾 lambda 參數(shù),以表示該 lambda 不進(jìn)行內(nèi)聯(lián)。
內(nèi)聯(lián)使用
內(nèi)聯(lián)函數(shù)只能提升帶有 lambda 參數(shù)的函數(shù)的性能。對于其余的函數(shù),內(nèi)聯(lián)無能為力。
內(nèi)聯(lián)函數(shù)必須非常小。如果函數(shù)很大,那么將函數(shù)復(fù)制到各個(gè)調(diào)用點(diǎn),將會極大增加字節(jié)碼的長度。
匿名函數(shù)
匿名函數(shù)與普通函數(shù)相似,除了 省略函數(shù)名及參數(shù)類型。
匿名函數(shù)的 return 語句從匿名函數(shù)中返回,而不是從包含匿名函數(shù)的函數(shù)中返回。
return 從最近使用 fun 關(guān)鍵字聲明的函數(shù)返回。因此,匿名函數(shù)的 return 返回匿名函數(shù),而 lambda 表達(dá)式的 return 返回調(diào)用 return 的函數(shù)。

- 匿名函數(shù)是 lambda 的另一種語法。因此,lambda 被內(nèi)聯(lián)時(shí)的限制一樣適用于匿名函數(shù)。