我正在尝试代码的出现,并希望在第10天创建一个类。我知道值可以为null,因此我将它们声明为可为空。在某些时候,我需要检查值是否已分配并对其执行某些操作。
问题来了。我事先通过high != null
检查,但在接下来的行中,我必须使用!!
来说服编译器它实际上是空的。
它似乎无法找到正确的compareTo
方法,尽管它首先进行了null检查。我猜,它没有智能播放我的变量
private class Bot(val number: Int, var low: Int?, var high: Int?) {
fun acceptValue(value: Int) {
if (low == null && high == null) {
high = value
} else {
if (high != null) {
if (high!! > value) { //it doesn't compile, because appareantly, high is still not considered nonnull at this point
low = value
} else {
low = high
high = value
}
}
}
}
}
kotlin-version使用的是1.1.3-2
这是一个错误吗?我做错了吗?
答案 0 :(得分:6)
由于您将high
定义为var
,因此它是可变的。即使在此之前有明确的空检查,也无法保证变量不为null。
请注意,当编译器无法保证变量在检查和使用之间无法更改时,智能强制转换不起作用。更具体地说,智能演员表适用于以下规则:
- val 局部变量 - 始终;
- val 属性 - 如果属性为private或internal,或者在声明属性的同一模块中执行检查。智能转换不适用于具有自定义getter的打开属性或属性;
- var 局部变量 - 如果在检查和使用之间没有修改变量,并且没有在修改它的lambda中捕获;
- var 属性 - 从不(因为其他代码可以随时修改变量)。
在您的情况下,您可以使用.let
:
high?.let {
if (it > value) {
low = value
} else {
low = it
high = value
}
} ?: run {
//high == null
}
建议阅读:In Kotlin, what is the idiomatic way to deal with nullable values, referencing or converting them
答案 1 :(得分:3)
在high != null
和high > value
之间,另一个线程可以执行high = null
,使空检查无效。所以这是预期的行为。
解决此问题的方法是使用无法从外部更改的临时变量:
val cHigh = high
if (cHigh != null) {
if (cHigh > value) {
....
答案 2 :(得分:1)
如果您声明属性var storage = {
getListUsers: function() {
return {
name: 'name',
age: 'age'
}
},
active: true,
data: []
}
var json = JSON.stringify(storage, function(key, value) {
if (typeof value === 'function') {
return value.toString();
} else {
return value;
}
});
console.log(json);
:
private