天天看點

kotlin 高階函數的注意事項

高階函數的注意事項

  • ​​高階函數的定義​​
  • ​​在 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();
      }
   }
}      

繼續閱讀