当我尝试创建以下代码时:
class SmartCast {
var array: MutableList<Int>? = null
fun processArray() {
if (array != null && !array.isEmpty()) {
// process
}
}
}
显示此错误:
很明显,在多线程的情况下,
array
变量可以更改为 null
。但是如果我使用 @Synchronized
注释,则无法改变 array != null
和 !array.isEmpty()
之间的变量。@Synchronized
fun processArray() {
我想知道,为什么编译器不允许在同步块(synchronized block)中进行智能转换,或者可能以某种方式指定我的应用程序仅适用于单线程模式?
UPDATE: 根据答案,我按以下方式更改了代码:
fun processArray() {
array?.takeUnless { it.isEmpty() }?.also {
for (elem in it)
// process elements
}
}
最佳答案
因为这
是错的。 @Synchronized
意味着这个方法不能同时被两个线程调用,但是另一个可以访问同一个实例的线程完全可以自由地重新分配 array
。
您还需要将 setter 标记为 @Synchronized
,在这种情况下,目前确实无法更改。但是试图弄清楚智能转换什么时候是安全的会导致非常复杂的规则,一种方法的微小变化会突然破坏其他方法中的智能转换。所以规则是保守的。
关于带有可为空变量的 Kotlin 智能转换,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50885684/