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

2023-12-30

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

lock(l) { foo() }

编译器可以发出以下代码,而不是为参数创建函数对象并生成调用。 (Source https://kotlinlang.org/docs/reference/inline-functions.html)

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

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

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

假设您创建了一个采用 lambda 类型的高阶函数() -> Unit(无参数,无返回值),并像这样执行:

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 object.


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

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

当你这样称呼它时:

inlined {
    println("do something here")
}

No Function将创建实例,而不是调用周围的代码block内联函数内部的内容将被复制到调用站点,因此您将在字节码中得到如下内容:

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

何时在 Kotlin 中使用内联函数? 的相关文章

随机推荐