天天看點

Kotlin語言之内聯函數

一、内聯函數

内聯函數是指用inline關鍵字修飾的函數。 在類内定義的函數被預設成内聯函數。 内聯函數從源代碼層看,有函數的結構,而在編譯後,卻不具備函數的性質。 内聯函數不是在調用時發生控制轉移,而是在編譯時将函數體嵌入在每一個調用處。

二、Java中的内聯函數

在java中不能顯式地聲明函數内聯,隻能間接通過JVM虛拟機實作。可以通過兩種方式向虛拟機提出請求,一種是使用final修飾:

public final void a(){
    statement
}
           

一種是把方法修飾為private

private void b(){
    statement
}
           

但是即使添加了這些标志,虛拟機也不一定會把方法内聯化,具體表現由虛拟機決定。

内聯的優點:減少函數棧調用成本。

内聯的缺點:代碼變長,占用更多記憶體空間和指令緩存。

三、Kotlin與内聯函數

Kotlin作為一種立志于替代java的語言,相較于java更多地使用了内聯函數這種特性以優化語言的程式設計表現。

如Kotlin标準庫中提供的let,apply函數:

public inline fun <T> T.apply(block: T.() -> Unit): T {
    contract {
        callsInPlace(block, InvocationKind.EXACTLY_ONCE)
    }
    block()
    return this
}
           

集合庫中建立可變list的mutableListOf函數:

public inline fun <T> mutableListOf(): MutableList<T> = ArrayList()
           

它們具有一個非常明顯的共同點,就是這些方法都會被頻繁調用。對頻繁調用的代碼内聯化,可以提高代碼效率降低調用成本。

在Kotlin中内聯函數需要指定inline關鍵字,是顯式聲明的,被聲明的函數都會被内聯化。Kotlin的内聯是編譯器實作的,可能會生成較多代碼,但不會對運作期性能有影響。

四、Kotlin的非内聯

有的時候隻需要内聯部分lamda參數,則可以通過noinline關鍵字修飾非内聯參數,比如:

inline fun foo(inlined: () -> Unit, noinline notInlined: () -> Unit) {  
  statement  
}  
           

内聯lamda表達式隻能在内聯函數中或作為内聯函數的參數。