Kotlin 的 inline、noinline、crossline function
Inline function
在重構(Refactor)裡有個技巧就叫inline。例如我們在main
呼叫了hello
這個function。
你可以在hello
上按右鍵 → Refactor → Inline function,就會把hello
這個function收回去變成:
反之,你也可以用Refactor裡的Extract function再把他提出到一個function。
那這裡我們要介紹的是 kotlin 的 function 裡有個關鍵字叫inline
,在一個function前面加上inline
,表示在編譯到Java程式碼時會把這個function收回去。
使用的方式是在 function 前面加上inline
。
我們來 Decompile 成 Java 看一下。點選 Tools → Kotlin → Show Kotlin Bytecode,再點 Decompile。你就會看到main裡面並沒有再去呼叫hello這個function了,而是直接執行你原本在hello function裡做的事。
但如果是一般的 function 這樣寫,IDE會警告:
Expected performance impact from inlining is insignificant. Inlining works best for functions with parameters of functional types.
意思就是除了在 functional type 裡使用,其實沒有太大的好處。建議你不要這樣使用。
那麼在 lambda 使用的好處是什麼呢?我們來看下面這段程式碼,寫了一個high order function 叫 hello
。
如果我們把他 Decompile,就會看到在Java的程式碼如下,會發現在傳遞function時,都會產生一個instance,也就是第3行的new Function0()
這樣產生instance的動作如果大量被執行,例如在一個迴圈裡,就會有較差的效能。
所以我們就會在 lambda function 前面加上inline。
再執行一次Tools → Kotlin → Show Kotlin Bytecode → Decompile,就可以看到原本寫在hello裡做的事,直接被 inline 到main
裡了。也就解決大量產生Instance的問題了。
在 Kotlin 的 scope function 裡的let
, run
, with
, apply
, also
這些function就都加了inline。
noinline
在一個inline function,如果有其中一個function參數不想被 inline,則在前面加上noinline
。
crossinline
下方程式碼因為hello有使用inline,在第4行我們加了 return
,會造成如下方程式碼的2個地方(第6行、第13行)不會再往下執行,這跟一般對於return
的定義會不太一樣。
我們可以加上crossinline
,這樣就會強迫你只能使用return@hello的寫法,如果直接使用return,IDE就會跳出錯誤來跟你說不能這樣寫。