Kotlin中的crossinline和noinline有什么区别? [英] What is the difference between crossinline and noinline in Kotlin?
问题描述
-
此代码编译时带有警告(对性能的影响不大):
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)可以编译?
-
noinline
和crossinline
之间到底有什么区别? - 如果(3)并没有带来性能上的改善,为什么(4)会呢?
- How come (2) does not compile but (4) does?
- What exactly is the difference between
noinline
andcrossinline
? - 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屋!