2017-06-10 3 views
26

私は、インライン関数がパフォーマンスを向上させる可能性があることを知っています&は、生成されたコードが大きくなる原因になりますが、正しく使用されているかどうかはわかりません。Kotlinでインライン関数を使用するのはいつですか?

lock(l) { foo() } 

代わりパラメータの関数オブジェクトを作成し、コールを生成する、コンパイラは、次のコードを放出する可能性があります。 (Source

l.lock() 
try { 
    foo() 
} 
finally { 
    l.unlock() 
} 

私は非インライン関数に対してkotlinによって作成されない関数オブジェクトが存在しないことを見出しました。どうして?

/**non-inline function**/ 
fun lock(lock: Lock, block:() -> Unit) { 
    lock.lock(); 
    try { 
     block(); 
    } finally { 
     lock.unlock(); 
    } 
} 
+4

これには2つの主な使用例があります.1つは特定の種類の高次関数で、もう1つはreified型のパラメータです。インライン関数のドキュメントには、次のものが含まれています。https://kotlinlang.org/docs/reference/inline-functions.html – zsmb13

+0

@ zsmb13ありがとうございます。私はそれを理解していません: "パラメータの関数オブジェクトを作成し、呼び出しを生成する代わりに、コンパイラは次のコードを発行することができます" –

+1

私はその例をtbh得る。 –

答えて

74

のは、あなたがタイプ() -> Unitのラムダ(パラメータなし、ノーリターン値)をとる高階関数を作成するとしましょう、などのようにそれを実行します。Javaの用語で

fun nonInlined(block:() -> Unit) { 
    println("before") 
    block() 
    println("after") 
} 

、この意志

public void nonInlined(Function block) { 
    System.out.println("before"); 
    block.invoke(); 
    System.out.println("after"); 
} 

としたときに

... Kotlinからそれを呼び出す:この(!簡体字)のようなものに変換ボンネットの下
nonInlined { 
    println("do something here") 
} 

Functionのインスタンスが(再び、これは単純化されている)、ラムダ内のコードをラップしている、ここで作成されます。

nonInlined(new Function() { 
    @Override 
    public void invoke() { 
     System.out.println("do something here"); 
    } 
}); 

だから、基本的には、この関数を呼び出すとラムダを渡します常にFunctionオブジェクトのインスタンスを作成します。一方


、あなたはinlineキーワードを使用する場合:いいえFunctionインスタンスは、代わりに、作成されません

inlined { 
    println("do something here") 
} 

:あなたはこのようにそれを呼び出すと

inline fun inlined(block:() -> Unit) { 
    println("before") 
    block() 
    println("after") 
} 

をインライン関数内のblockの呼び出しのコードがコールサイトにコピーされるので、バイトコードの中で次のようなものが得られます:

この場合、新しいインスタンスは作成されません。

+0

最初にFunctionオブジェクトラッパーを持つ利点は何ですか?つまり、なぜすべてがインライン化されていないのですか? –

+3

このようにして、関数をパラメータとして任意に渡したり、変数に格納したりすることもできます。 – zsmb13

+0

@ zsmb13 – Yajairo87

関連する問題