具有可为空变量的Kotlin Smart Cast [英] Kotlin smart cast with nullable variable

查看:67
本文介绍了具有可为空变量的Kotlin Smart Cast的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

When I'm trying to create the following code:

class SmartCast {
    var array: MutableList<Int>? = null

    fun processArray() {
        if (array != null && !array.isEmpty()) {
            // process
        }
    }
}

显示此错误:

不可能将类型强制转换为"MutableList",因为"array"是 这次可能已经更改的可变属性

Smart cast to 'MutableList' is impossible, because 'array' is a mutable property that could have been changed by this time

很明显,在多线程的情况下,可以将array变量更改为null.但是,如果我使用@Synchronized注释,则无法在array != null!array.isEmpty()之间对变量进行突变.

It's clear that the array variable can be changed to null in case of multi-threading. But if I use @Synchronized annotation, there is no way to mutate the variable in between array != null and !array.isEmpty().

@Synchronized
fun processArray() {

我很好奇,为什么编译器不允许在同步块中进行智能转换,或者也许可以指定我的应用程序仅设计用于单线程模式?

I'm wonder, why the compiler doesn't allow smart cast in synchronized blocks or maybe it's possible to specify somehow that my application is designed only for single-threaded mode?

更新:根据答案,我通过以下方式更改了代码:

UPDATE: According to the answers, I changed the code in the following way:

fun processArray() {
    array?.takeUnless { it.isEmpty() }?.also {
        for (elem in it)
            // process elements
    }
}

推荐答案

为什么编译器不允许在同步块中进行智能投射

why the compiler doesn't allow smart cast in synchronized blocks

因为这个

但是,如果我使用@Synchronized批注,则无法在数组!= null和!array.isEmpty()之间对变量进行突变.

But if I use @Synchronized annotation, there is no way to mutate the variable in between array != null and !array.isEmpty().

是错误的. @Synchronized表示不能由两个线程同时调用此方法,但是可以访问同一实例的另一个线程可以完全自由地重新分配array.

is wrong. @Synchronized means this method can't be called by two threads at the same time, but another thread which has access to the same instance is perfectly free to reassign array.

您还需要将设置器标记为@Synchronized,在这种情况下,它现在暂时无法更改.但是,试图弄清楚智能投射的安全性何时会导致非常复杂的规则,一种方法的微小更改突然会破坏其他方法的智能投射.因此规则是保守的.

You also need to mark the setter as @Synchronized, in which case it really can't be changed at the moment. But trying to figure out exactly when smart casts are safe would lead to very complex rules, and minor changes in one method suddenly breaking smart casts in others. So the rules are conservative instead.

这篇关于具有可为空变量的Kotlin Smart Cast的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆