KC Blog

【Android/Kotlin】極速掌握 inline / noinline / crossinline 三大關鍵字教學!

6 min read
ProgrammingLang#Android

前言

在 Kotlin 編程中,inline、noinline 和 crossinline 是常見的關鍵字。

這些關鍵字可以在函數聲明中使用,

它們可以對函數進行不同的行為修改,

進而影響代碼的運行方式和性能。

本篇文章將詳細介紹這三個關鍵字的使用方式和區別,

並提供相關的代碼示例和實際應用場景。

inline

inline 實際上的作用,

就是會在編譯的時候把你有使用inline的function內容直接複製到執行處,

而不是直接實例化一個物件,

藉由inline來減少實例化物件來提升效能

先簡單的說,我們寫一個funcion會寫成像下方這樣:

然而,如果帶入一般變數的function直接加上inline,

某些IDE可能會提醒你這樣直接使用,

並不會增加效能表現。 像是下面這邊示範,

只有帶入一般變數並使用inline,

則編譯器跳黃底提醒,

說明了預期要帶入function type 變數才能有效提升效能表現。

Cover

所以,我們試著寫出一個帶入function type的function,

並寫一個一樣的function帶有inline,就像這樣:

這兩個執行後你會發現返回的結果一樣,

但是實際上,

如果你反編譯這段code出來看的話(如下),

你會發現,沒有用inline,

程式在跑的時候,

會針對你的lambda function創建一個新的instance,

也就是會實例化一個新的物件,

如果你剛好有一段code需要重複運用到這個function,

他就會重複創建物件,

因此可能會花比較多效能去處理這個lambda function,

所以如果使用inline 就可以降低這方面效能的消耗。

提示:(Function1)null.INSTANCE,是反編譯器找不到等效的Java 類的顯示。

從上面的例子可以單看出,使用lambda function的當下,

如果用inline,可以提升處理的效能,

但實際上,我們會使用的時機呢?這邊我舉個例子

假設你有個情境,是需要重複呼叫某個帶有lambda 的function,比較沒經驗的可能會直接這樣寫:

可以看到,在你反編譯後,

你會看到你雖然達成了你用的重複執行10次,

但同時,你也重複創建了10次同樣的物件,

所以當你比較有經驗後,你可以:

1.把lambda function在迴圈外部創建

這樣同樣能提升效能,但既然都使用kotlin了,那就使用inline也可以。

2.使用inline來創建:

這樣的話,你就能看出,使用inline的優勢,

好了,接下來說說noinline 跟crossinline有什麼差別嗎,

其實剩下這兩個關鍵字,

我感覺是用來輔助inline的,

他不像inline一樣,是加在fun前面,

他反而是用來設定function type(or lambda function)的。

noinline
noinline的概念,其實更簡單了,

當你了解inline,就會明白為何我說這兩個是輔助了,

這個的用途,

是當你一個inline function內含有多個function type時,

你可以去控制,哪個lambda 要使用inline,例如:

因此,你也能依照需求,去選擇要不要用inline

crossinline
先來個前導概念:

當你在使用lambda function時,

如果在宣告的lambda function 裡面加入return ,

會導致呼叫時,使用lambda function的地方直接return出該function:

這時候,你不想要跳出整個inline function ,

你可以用像上方code提到的,直接將原本的return改成 return@getMinutesWithInline 這樣,

他就只會跳出宣告的lambda function。

或是你也能使用crossinline的關鍵字,

他也是用來修飾lambda function的,

也是輔助inline使用的,

功效是可以避免有return時,直接被return出去!

結論

使用 inline

能夠降低程式呼叫lambda function時重複創建實例化

藉此提升效率

使用 inline 能避免建立過多的實例化物件

使用 noinline 可以讓lambda 不使用inline

使用 crossinline 可以避免lambda 中的 return 影響外部程式流程

inline / noinline / crossinline範例程式碼