何时在Kotlin中使用内联函数? [英] when to use an inline function in Kotlin?

查看:189
本文介绍了何时在Kotlin中使用内联函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

  lock(l){ foo()} 




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




  l.lock()
尝试{
foo()
}
finally {
l.unlock()
}

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

  / **非内联函数** / 
fun lock(lock:Lock,block :( ) - > Unit){
lock.lock();
尝试{
block();
} finally {
lock.unlock();


$ / code $ / pre

解决方案

假设你创建一个高阶函数,它需要一个() - >类型的lambda表达式。单元(没有参数,没有返回值),并像这样执行它:

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

用Java的说法,这将转化为这样的事情(简化!):

$ b pre> public void nonInlined(Function block){
System.out.println(before);
block.invoke();
System.out.println(after);
}

当你从Kotlin调用它时...

  nonInlined {
println(在此做某事)
}

在这里创建一个 Function 的实例,它将代码包装在lambda

  nonInlined(new Function(){
@Override
public void invoke(){
System.out.println(在这里做某事);
}
});

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






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

  inline fun inlined(block:() - >单位){
println(before)
block()
println(after)
}

当您像这样调用它时:

 内嵌{b $ b println(在此做某事)
}

函数实例将被创建,相反,在内联函数内调用的代码将被复制到调用站点,在字节码中会得到这样的内容:

  System.out.println(before); 
System.out.println(在这里做某事);
System.out.println(after);

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


I know that an inline function will maybe improve performance & cause the generated code to grow, but I'm not sure when it is correctly to use it.

lock(l) { foo() }

Instead of creating a function object for the parameter and generating a call, the compiler could emit the following code. (Source)

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

but I found that there is no function object created by kotlin for a non-inline function. why?

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

解决方案

Let's say you create a higher order function that takes a lambda of type () -> Unit (no parameters, no return value), and executes it like so:

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

In Java parlance, this will translate to something like this (simplified!):

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

And when you call it from Kotlin...

nonInlined {
    println("do something here")
}

Under the hood, an instance of Function will be created here, that wraps the code inside the lambda (again, this is simplified):

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

So basically, calling this function and passing a lambda to it will always create an instance of a Function object.


On the other hand, if you use the inline keyword:

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

When you call it like this:

inlined {
    println("do something here")
}

No Function instance will be created, instead, the code around the invocation of block inside the inlined function will be copied to the call site, so you'll get something like this in the bytecode:

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

In this case, no new instances are created.

这篇关于何时在Kotlin中使用内联函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆