高階函數的注意事項
- 高階函數的定義
- 在 kotlin 中,函數是 "一等公民"
- 注意
- 用内聯優化代碼
高階函數的定義
函數(or lambde) 的參數又是 函數(or lambde),這樣的函數我們稱之為高階函數
fun main(args: Array<String>) {
onlyif(true){
println("print log")
}
}
fun onlyif(isDebug: Boolean, block:() -> Unit){
if (isDebug) block()
}
在 kotlin 中,函數是 “一等公民”
val runnable = Runnable {
println("as")
}
val function: () -> Unit//聲明一個參數為空的函數對象
function = runnable::run//可以這樣去直接引用函數聲明
注意
在高階函數的參數中,要想作為參數傳遞給高階函數的時候,必須得要是傳遞函數的聲明,如果傳的是直接執行一個函數的話,那麼實際上傳遞的是函數的傳回值
上面的代碼直接跑是不列印
as
的,改成如下形式就好了:
fun main(args: Array<String>) {
val runnable = Runnable {
println("as")
}
val function: () -> Unit
function = runnable::run
onlyif(true, function)
}
inline fun onlyif(isDebug: Boolean, block:() -> Unit){
if (isDebug) block()
}
用内聯優化代碼
- Kotlin 的 Lambda 表達式會被編譯成是一個匿名對象的形式
- 如果代碼中有大量重複的 lambda 表達式,代碼會生成很多臨時的無用對象
- 可以使用 inline 關鍵字去修飾高階函數,這樣當方法在編譯時就會拆解函數的調用語句為語句調用,進而減少建立不必要的對象
- 過度使用 inline 關鍵字,會增加編譯器的編譯的負擔,同時會使代碼塊變的很龐大,查找起問題很麻煩,是以 inline 通常隻會用于修飾高階函數
public final class TestKt {
public static final void main(@NotNull String[] args) {
onlyif(true, (Function0)null.INSTANCE);
}
public static final void onlyif(boolean isDebug, @NotNull Function0 block) {
if (isDebug) {
block.invoke();
}
}
}