为了简化我的实际用例,假设我想找到列表中的最大数字:
var max : Int? = null
listOf(1, 2, 3).forEach {
if (max == null || it > max) {
max = it
}
}
但是,编译失败并出现以下错误:
智能转换为“Int”是不可能的,因为“max”是一个由变化的闭包捕获的局部变量
为什么改变闭包会阻止智能转换在此示例中工作?
一般来说,当在 lambda 函数闭包中捕获可变变量时,智能强制转换不适用于该变量,无论是在 lambda 内部还是在创建 lambda 后的声明范围内。
这是因为该函数可能会脱离其封闭范围,并可能稍后在不同的上下文中执行,可能多次执行,也可能并行执行。作为一个例子,考虑一个假设函数List.forEachInParallel { ... }
,它为列表中的每个元素执行给定的 lambda 函数,但并行。
编译器必须生成即使在这种严重情况下也能保持正确的代码,因此它不会假设变量的值在空检查后保持不变,因此无法对其进行智能转换。
然而,List.forEach
是完全不同的,因为它是一个inline https://kotlinlang.org/docs/reference/inline-functions.html功能。内联函数的主体及其函数参数的主体(除非参数具有noinline
or crossinline
修饰符)在调用站点内联,因此编译器可以推断作为参数传递给内联函数的 lambda 中的代码,就好像它是直接编写在调用方法主体中一样,从而使智能转换成为可能。
可以,但目前还不行。仅仅是因为该功能尚未实现。有一个悬而未决的问题:KT-7186 https://youtrack.jetbrains.com/issue/KT-7186.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)