【问题标题】:When lambda parameters must be noinline in Kotlin?什么时候 lambda 参数必须在 Kotlin 中为 noinline?
【发布时间】:2017-12-02 17:24:42
【问题描述】:

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

内联 lambda 只能在内联函数内部调用,或者 作为 inlinable 参数传递,但 noinline 可以在 我们喜欢的任何方式:存储在字段中,传递等等。

我无法解开这些概念。具体来说,我不确定我是否完全理解我 不能 使用内联 lambda 做的事情(包括“等”中的所有内容)——换句话说,那些会取消它被内联的资格。 是否有很好的参考或更多解释/示例说明使 Kotlin lambda 参数无法内联的用法?

【问题讨论】:

    标签: lambda kotlin inline


    【解决方案1】:

    与其说是“取消”内联 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 做的是将其视为对象

    这意味着您不能将其存储在字段中:

    val a = lambda // <-- error
    

    或在其上调用方法:

    lambda.toString() // <-- error
    

    因为它不是一个对象。

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

    func(lambda) // <-- error
    

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

    这基本上由文档说明。

    noinline 可以以我们喜欢的任何方式进行操作:存储在字段中、传递等等。

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

    将内联 lambda 视为将它们的 代码 直接插入到方法中。从概念上讲,它们实际上并不存在,“调用”它们只会将它们的内容插入到调用方法中。

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 1970-01-01
      • 2014-02-03
      • 1970-01-01
      • 2014-11-08
      • 2013-10-23
      • 1970-01-01
      • 2011-03-18
      • 2012-04-26
      相关资源
      最近更新 更多