Kotlin 的 inline、noinline、crossline function

Evan Chen
Evan Android Note
Published in
Jun 6, 2022

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就會跳出錯誤來跟你說不能這樣寫。

--

--