此代码编译时出现警告(对性能影响不大):
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() }
}
这是我的问题:
noinline
和crossinline
到底有什么区别?最佳答案
来自 inline functions reference :
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
不需要这种行为(显然,因为它是一个普通的函数参数)。
示例 1 和示例 3 不会产生任何性能改进,因为唯一的 lambda 参数被标记为 noinline
,导致函数的 inline
修饰符无用且冗余 - 编译器想要内联一些东西,但所有可能被标记为不被内联的东西。
考虑两个函数,A 和 B
inline fun test(noinline f: () -> Unit) {
thread { f() }
}
fun test(f: () -> Unit) {
thread { f() }
}
函数 A 的行为类似于函数 B,因为参数 f
不会被内联(B 函数没有内联 test
的主体,而在 A 函数中,主体: thread { f() }
仍然被内联) .
现在,在示例 4 中并非如此,因为 crossinline f: () -> Unit
参数 可以 内联,所以它不能违反上述非-local 控制流规则(例如为全局变量分配新值)。如果它可以被内联,编译器会假设性能得到提升,并且不会像示例 3 中那样发出警告。
https://stackoverflow.com/questions/38827186/