Kotlin中的crossinline和noinline有什么区别? [英] What is the difference between crossinline and noinline in Kotlin?

查看:498
本文介绍了Kotlin中的crossinline和noinline有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  1. 此代码编译时带有警告(对性能的影响不大):

inline fun test(noinline f: () -> Unit) {
    thread(block = f)
}

  • 此代码无法编译(内联参数的非法使用):

    inline fun test(crossinline f: () -> Unit) {
        thread(block = f)
    }
    

  • 此代码编译时带有警告(对性能的影响不大):

    inline fun test(noinline f: () -> Unit) {
        thread { f() }
    }
    

  • 此代码编译时无警告或错误:

    inline fun test(crossinline f: () -> Unit) {
        thread { f() }
    }
    

  • 这是我的问题:

    • 为什么(2)不能编译,但是(4)可以编译?
    • noinlinecrossinline之间到底有什么区别?
    • 如果(3)并没有带来性能上的改善,为什么(4)会呢?
    • How come (2) does not compile but (4) does?
    • What exactly is the difference between noinline and crossinline?
    • If (3) does not generates a no performance improvements, why would (4) do?

    推荐答案

    来自内联函数参考:

    请注意,某些内联函数可能不直接从函数主体而是从另一个执行上下文(例如本地对象或嵌套函数)调用作为参数传递给它们的lambda.在这种情况下,lambda中也不允许非本地控制流.为了表明这一点,需要用crossinline修饰符标记lambda参数

    Note that some inline functions may call the lambdas passed to them as parameters not directly from the function body, but from another execution context, such as a local object or a nested function. In such cases, non-local control flow is also not allowed in the lambdas. To indicate that, the lambda parameter needs to be marked with the crossinline modifier

    因此,示例2无法编译,因为crossinline仅强制执行本地控制流,而表达式block = f违反了该控制流.编译示例1,因为noinline不需要这样的行为(显然,因为它是一个普通的函数参数).

    Hence, example 2. doesn't compile, since crossinline enforces only local control flow, and the expression block = f violates that. Example 1 compiles, since noinline doesn't require such behavior (obviously, since it's an ordinary function parameter).

    示例1和3不会产生任何性能改进,因为唯一的lambda参数被标记为noinline,从而使该函数的inline修饰符变得无用和多余-编译器希望内联某些东西,但是可以be已被标记为不内联.

    Examples 1 and 3 do not generate any performance improvements, since the only lambda parameter is marked noinline, rendering the inline modifier of the function useless and redundant - the compiler would like to inline something, but everything that could be has been marked not to be inlined.

    考虑两个功能, A B

    inline fun test(noinline f: () -> Unit) {
        thread { f() }
    }
    

    B

    fun test(f: () -> Unit) {
        thread { f() }
    }
    

    函数 A 的行为与函数 B 相似,因为不会内联参数f( B 函数不会内联test的正文,而在 A 函数中,正文:thread { f() }仍内联).

    Function A behaves like function B in the sense that the parameter f will not be inlined (the B function doesn't inline the body of test whereas in the A function, the body: thread { f() } still gets inlined).

    现在,在示例4中,情况并非如此,由于可以内嵌crossinline f: () -> Unit参数 ,因此它不能违反上述非本地控制流规则(例如,将新值分配给全局变量).而且,如果可以内联,则编译器将假定性能有所提高,并且不会像示例3中那样发出警告.

    Now, this is not true in the example 4, since the crossinline f: () -> Unit parameter can be inlined, it just cannot violate the aforementioned non-local control flow rule (like assigning new value to a global variable). And if it can be inlined, the compiler assumes performance improvements and does not warn like in the example 3.

    这篇关于Kotlin中的crossinline和noinline有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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