为了简化我的真实用例,让我们假设我想在一个列表中找到最大的数字:
var max : Int? = null
listOf(1, 2, 3).forEach {
if (max == null || it > max) {
max = it
}
}
但是,编译失败并出现以下错误:
智能强制转换为“Int”是不可能的,因为“max”是一个由变化的闭包捕获的局部变量
为什么更改的闭包会阻止智能强制转换在此示例中起作用?
在我看来,这像是一个编译器错误。
如果foreach
中的内联lambda参数被标记为交叉线
,那么我预计会出现编译错误,因为可能会并发调用lambda表达式。
请考虑以下foreach
实现:
inline fun <T> Iterable<T>.forEach(crossinline action: (T) -> Unit): Unit {
val executorService: ExecutorService = ForkJoinPool.commonPool()
val futures = map { element -> executorService.submit { action(element) } }
futures.forEach { future -> future.get() }
}
如果没有交叉线
修饰符,上述实现将无法编译。没有它,lambda 可能包含非本地回报,这意味着它不能以并发方式使用。
我建议创建一个问题:科特林(KT)|搜狐.
感谢伊利亚对问题的详细解释!您可以使用标准的<code>for(列表中的项){…}</code>表达式,如下所示:
var max : Int? = null
val list = listOf(1, 2, 3)
for(item in list){
if (max == null || item > max) {
max = item
}
}
一般来说,当可变变量在lambda函数闭包中被捕获时,无论是在lambda内部还是在lambda创建后的声明范围内,智能强制转换都不适用于该变量。
这是因为函数可能会脱离其封闭范围,并可能在以后的不同上下文中执行,可能是多次执行,也可能是并行执行。例如,考虑一个假设的函数< code>List.forEachInParallel {...},它对列表中的每个元素执行给定的lambda函数,但是是并行的。
编译器必须生成即使在这种严重情况下也能保持正确的代码,所以它不会假设变量的值在空检查后保持不变,因此不能对其进行智能转换。
但是,<code>是一个列表。forEach非常不同,因为它是一个<code>内联
它可以,但目前,它没有。仅仅因为该功能尚未实现。它有一个悬而未决的问题:KT-7186。
我知道这个问题以前有人问过,但似乎没有解决方案。我正在尝试使用名为的int变量来跟踪的顶部可见项目,该变量通过将视图的标记(类型“Any”)转换为Int来填充:
当我构建我的项目时,我得到了这个错误 下面是kotlin类代码 我不知道如何解决它
我知道是可变变量,但我显式检查了并且是类型,那么为什么不能智能转换为该类型呢? 我怎样才能把它修好呢?
我正在尝试在 Kotlin 中生成一个单例,并且遇到了问题,因为我无法。 这似乎是制作单例的一种非常标准的方法。为什么它不让我,我该如何解决它?
我已经使用android studio内置的文件转换器将java文件转换为kotlin。它显示以下错误。 [SMARTCAST_IMPOSSIBLE]智能强制转换为“ReminderRequester”是不可能的,因为“ReminderRequester”是一个可变属性,此时可能已被更改 我查过类似的问题,但我不能正确地理解它。 上述错误的含义是什么?如何修复?
所以我最近开始学习Kotlin,我正在学习Java语言的Android Studio教程。我最终使用Android Studio将Java文件转换为Kotlin。 如何修复此错误?