何时在Kotlin中使用内联函数?

我知道一个内联函数可能会提高性能,并导致生成的代码增长,但我不知道什么时候使用它是正确的。

lock(l) { foo() } 

编译器可以发出下面的代码,而不是为参数创建一个函数对象并生成一个调用。 ( 来源 )

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

但是我发现kotlin没有为非内联函数创建函数对象。 为什么?

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

假设你创建一个更高阶的函数,它需要一个类型为() -> Unit (无参数,无返回值)的lambda表达式,并像下面这样执行它:

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

按照Java的说法,这将转化为像这样(简化!):

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

而当你从Kotlin打电话给…

 nonInlined { println("do something here") } 

在这里, Function一个实例将在这里被创建,它将代码包装在lambda中(同样,这被简化了):

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

所以基本上,调用这个函数并传递一个lambda到它总是会创建一个Function对象的实例。


另一方面,如果您使用inline关键字:

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

当你这样称呼它时:

 inlined { println("do something here") } 

没有Function实例会被创建,相反,围绕在内嵌函数中的block调用的代码将被复制到调用站点,所以你会得到这样的字节码:

 System.out.println("before"); System.out.println("do something here"); System.out.println("after"); 

在这种情况下,不会创建新的实例。

    Interesting Posts