Kotlin智能投射具有可空变量

时间:2018-06-16 06:55:13

标签: kotlin

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

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

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

显示此错误:

  

智能转换为'MutableList'是不可能的,因为'array'是一个   可以在这个时候改变的可变属性

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

@Synchronized
fun processArray() {

我很奇怪,为什么编译器不允许在同步块中进行智能强制转换,或者可能以某种方式指定我的应用程序仅针对单线程模式设计?

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

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

3 个答案:

答案 0 :(得分:4)

将列表保存到局部变量,并使用该局部变量。一种优雅的方法是使用let函数,并将其与null-safe运算符组合:

array?.let { 
    if (!it.isEmpty()) {
        // process it
    }
}

idioms section of the getting started guide,BTW。

中对此进行了描述

答案 1 :(得分:3)

  

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

因为这个

  

但是如果我使用@Synchronized注释,就无法在数组!= null和!array.isEmpty()之间改变变量。

错了。 profit = [] tax_profit = [] p_margin = [] mean = 0 for i in range(0,len(revenue)): profit.append(revenue[i] - expenses[i]) print ("The profit per month is",profit) print("\n") for i in range(0,len(profit)): tax_profit.append(profit[i] * 70/100) print("The profit after tax is",tax_profit) print("\n") for i in range(0,len(tax_profit)): p_margin.append((tax_profit[i]/revenue[i])) print(p_margin) p_margin = [round(i,2) for i in p_margin] print(p_margin) print("\n") mean_pat = sum(profit) / len(profit) print(mean_pat) good_months = [] bad_months = [] for i in range (0, len(tax_profit)): good_months.append(tax_profit[i] > mean_pat) print(good_months) for i in range (0, len(tax_profit)): bad_months.append(tax_profit[i] < mean_pat) print(bad_months) best_month = [] for i in range (0, len(tax_profit)): best_month.append(tax_profit[i] == max(tax_profit)) print(best_month) print (round(tax_profit[i],2)) print("\n") worst_month = [] for i in range (0, len(tax_profit)): worst_month.append(tax_profit[i] == min(tax_profit)) print(worst_month) print(round(tax_profit[i],2)) > the output for best month and worst month is coming out to be same. > Although the month having the worst month is showing True but printing the equivalent value of the worst month incorrectly by giving the value of the best month. 表示此方法不能同时由两个线程调用,但另一个可以访问同一实例的线程可以完全自由地重新分配@Synchronized

您还需要将设置器标记为array,在这种情况下,它实际上无法更改。但是试图弄清楚智能演员阵容何时是安全的会导致非常复杂的规则,而一种方法的微小变化会突然打破其他人的智能演员阵容。因此规则是保守的。

答案 2 :(得分:0)

Kotlin 1.3为此引入了function

fun <T> Collection<T>?.isNullOrEmpty(): Boolean

所以

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

    fun processArray() {

        if(!array.isNullOrEmpty()){
            // processs
        }
    }
}

将编译。