原因/定義:
使用高階函數會帶來一些運作時的效率損失:每一個函數都是一個對象,并且會捕獲一個閉包;即那些在函數體内會通路到的變量;記憶體配置設定(對于函數對象和類)和虛拟調用會引入運作時間開銷。但是在許多情況下通過“内聯化lambda表達式”可以消除這類的開銷。
普通函數怎麼定義成内聯函數?
實作:
就是在前面加“inline”關鍵字
inline fun printMsg(){
println("Hello, Kotlin!!!")
}
就這樣,“printMsg()”就是一個内聯函數了。
作用:
減少函數調用以及是以引起的開銷,優化性能;inline 修飾符影響函數本身和傳給它的 lambda 表達式:所有這些都将内聯到調用處。
在實際使用中,高階函數更适合定義為内聯函數:米茨調用高階函數,都會傳一個lambda表達式,而這個lambda表達式是一個匿名函數的文法糖,談本市也是一個函數。
下面直接上代碼說明:
costs {
println("Hello, Kotlin!!!")
}
inline fun costs(block:() -> Unit){
val start = System.currentTimeMillis();
block()
println("${System.currentTimeMillis() - start}")
}
上面的示例代碼,我們可以這樣了解:
“costs(block:() -> Unit)”函數裡面的參數(本質上是個方法)block就是上面的 costs {println(“Hello, Kotlin!!!”)}裡面的“println(“Hello, Kotlin!!!”)”
當系統真正調用執行的時候,本質上相當于這樣:
val start = System.currentTimeMillis();
println("Hello, Kotlin!!!")
println("${System.currentTimeMillis() - start}")
高階函數的内聯說明:
1、函數本身,也就是“costs()”被内聯到調用處
2、函數的函數參數,也就是“block:()”,本質上是“println(“Hello, Kotlin!!!”)”被内聯到調用處
注意事項:
1、内聯可能導緻生成的代碼增加;不過如果我們使用得當(即避免内聯過大函數),性能上會有所提升,尤其是在循環中的“超多态(megamorphic)”調用處。
2、public/protected修飾的内聯方法隻能通路對應類的public成員;
3、内聯函數的内聯函數參數不能夠被儲存(指派給變量);
4、内聯函數的内聯函數參數隻能傳遞給其他内聯函數參數。
5、上面2、3、4三點簡單來說,就是:public/protected隻能通路public修飾的方法;内聯隻能通路内聯;内聯函數的參數不能夠被存儲。
題外話:
val mIntArray: Array<Int> = arrayOf(1,2,3,4,5,6)
mIntArray.forEach {
if (it == 4){
println("找到了目标:$it")
//小細節:這裡“[email protected]”僅僅是當it==4時,傳回到“forEach”處繼續執行,隻是不執行“forEach”這條語句。
[email protected]
}
println("$it")
}
//上面的實作等價于下面的寫法:
for (i in mIntArray) {
if (i == 4){
println("找到了目标:$i")
//小細節:這裡“[email protected]”僅僅是當it==4時,傳回到“forEach”處繼續執行,隻是不執行“forEach”這條語句。
continue
}
println("i = $i")
}
二者運作擠過如下:

現在我們把上面for循環裡面的“continue”關鍵字改為“break”關鍵字,然後再運作:
for (i in mIntArray) {
if (i == 4){
println("找到了目标:$i")
//小細節:這裡“[email protected]”僅僅是當it==4時,傳回到“forEach”處繼續執行,隻是不執行“forEach”這條語句。
break
}
println("i = $i")
}
結果如下: