-
这段代码编译时有警告 (性能影响微不足道):
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
and crossinline
?
- 如果 (3) 没有产生性能改进,为什么 (4) 会产生性能改进呢?
来自内联函数参考 https://kotlinlang.org/docs/reference/inline-functions.html:
请注意,某些内联函数可能会调用作为参数传递给它们的 lambda,而不是直接从函数体直接调用,而是从另一个执行上下文(例如本地对象或嵌套函数)调用。在这种情况下,lambda 中也不允许非本地控制流。为了表明这一点,lambda 参数需要使用 crossinline 修饰符进行标记
因此,示例 2. 无法编译,因为crossinline
仅强制执行本地控制流,并且表达式block = f
违反了这一点。示例 1 可以编译,因为noinline
不需要这样的行为(显然,因为它是一个普通的函数参数)。
示例 1 和 3 不会产生任何性能改进,因为唯一的 lambda 参数被标记为noinline
,渲染inline
函数的修饰符无用且多余 - 编译器想要内联某些内容,但所有可能的内容都已标记为不内联。
考虑两个函数,A and B
A
inline fun test(noinline f: () -> Unit) {
thread { f() }
}
B
fun test(f: () -> Unit) {
thread { f() }
}
功能A行为类似于函数B从某种意义上说,参数f
不会被内联(B函数没有内联函数体test
而在A功能、身体:thread { f() }
仍然被内联)。
现在,在示例 4 中情况并非如此,因为crossinline f: () -> Unit
范围can被内联,它只是不能违反前面提到的非局部控制流规则(比如为全局变量分配新值)。如果它可以被内联,编译器就会假设性能得到改进,并且不会像示例 3 中那样发出警告。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)