当我尝试创建以下代码时:

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/

10-09 00:39