首页 文章

什么时候lambda参数在Kotlin中必须是noinline?

提问于
浏览
3

我经常在Kotlin内联函数中遇到错误,其中lambda参数必须标记为 noinline . 其他时候,lambda参数似乎工作正常 . 我已经阅读了inline functions的Kotlin文档,看起来这是解释规则的操作段落:

Inlinable lambdas只能在内联函数内部调用或作为inlinable参数传递,但是无内容可以以我们喜欢的任何方式进行操作:存储在字段中,传递等等 .

我'm having trouble unpacking those concepts. Specifically, I'我不确定我是否完全理解我所做的事情(包括所有在_831687中的内容)和一个内联的lambda - 换句话说,那些会使它无法被内联的东西 . Is there a good reference or more explanation/examples of uses that disqualify a Kotlin lambda parameter from being inlined?

1 回答

  • 4

    它不会使lambda“被取消资格”,更多的是“这个动作无法在内联的lambda上执行” .

    我有点回答了这个问题here .

    内联方法直接插入到调用站点中,任何内联lambda都是如此 .

    重用我的旧例子,

    这大致导致 main 在这里:

    fun withLambda(lambda: () -> Unit) {
        lambda()
    }
    
    inline fun inlinedLambda(lambda: () -> Unit) {
        lambda()
    }
    
    fun main(args: Array<String>) {
        withLambda { println("Hello, world") }
        inlinedLambda { println("Hello, world") }
    }
    

    被转换为:

    fun main(args: Array<String>) {
        withLambda { println("Hello, world") }
        println("Hello, world") // <- Directly inserted!
    }
    

    内联lambda无法做到的是 treat it like an object .

    这意味着您无法将其存储在字段中:

    val a = lambda // <-- error
    

    或者在其上调用方法:

    lambda.toString() // <-- error
    

    因为它不是一个对象 .

    它也不能作为参数传递给另一个函数

    func(lambda) // <-- error
    

    除非lambda标记为crossinline,另一个函数的参数是 inline .

    这基本上由文档说明 .

    noinline可以任何我们喜欢的方式操纵:存储在字段中,传递等等 .

    请注意,一些内联函数可能会将传递给它们的lambda作为参数调用...为了表明这一点,lambda参数需要使用crossinline修饰符进行标记:

    将内联lambda视为将其代码直接插入到方法中 . 从概念上讲,它们实际上并不存在,并且"calling"它们只是将它们的内容插入到调用方法中 .

相关问题