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

时间:2017-12-02 06:09:33

标签: lambda kotlin inline

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

  

Inlinable lambdas只能在内联函数内部调用   作为无可辩驳的论点传递,但是可以操纵无内线的参数   我们喜欢的任何方式:存储在字段中,传递等等。

我在解开这些概念时遇到了麻烦。具体来说,我不确定我完全理解我不能做的事情(包括所有在“等”中的内容)和内联lambda - 换句话说,就是取消其内联资格。 是否有一个很好的参考或更多解释/使用例子来取消Kotlin lambda参数的内联资格?

1 个答案:

答案 0 :(得分:5)

不太重要"取消资格"内联的lambda和更多的"这个动作不能在内联的lambda上执行。"

我有点回答here

内联方法直接插入到调用站点中,就像任何内联的lambdas一样。

重用我的旧例子,

这大致导致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作为参数调用...为了表明这一点,lambda参数需要用crossinline修饰符标记:

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