当我尝试创建以下代码时:
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
}
}
答案 0 :(得分:4)
将列表保存到局部变量,并使用该局部变量。一种优雅的方法是使用let
函数,并将其与null-safe运算符组合:
array?.let {
if (!it.isEmpty()) {
// process it
}
}
中对此进行了描述
答案 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
}
}
}
将编译。