我正在尝试代码的出现,并希望在第10天创建一个类.我知道值可以为null,因此我将它们声明为可空.在某些时候,我需要检查值是否已分配并对其执行某些操作.问题来了.我事先检查过high != null,但在接下来的行中,我必须!!用来说服编译器它实际上是null.
它似乎找不到合适的compareTo方法,尽管首先进行了无效检查.我猜,它没有智能播放我的变量
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
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
kotlin版是用的 1.1.3-2
那是一个错误吗?难道我做错了什么?
既然你被定义high为a var,它是可变的.即使在此之前有明确的空检查,也无法保证变量不为null.
官方解释:
请注意,当编译器无法保证变量在检查和使用之间无法更改时,智能强制转换不起作用.更具体地说,智能演员表适用于以下规则:
- val局部变量 - 总是;
- val属性 - 如果属性是私有属性或内部属性,或者在声明属性的同一模块中执行检查.智能模型不适用于具有自定义getter的开放属性或属性;
- var局部变量 - 如果在检查和使用之间没有修改变量,并且没有在修改它的lambda中捕获;
- var属性 - 从不(因为变量可以在任何时候被其他代码修改).
在你的情况下,你可以使用.let:
high?.let {
if (it > value) {
low = value
} else {
low = it
high = value
}
} ?: run {
//high == null
}
Run Code Online (Sandbox Code Playgroud)
建议阅读:在Kotlin中,处理可空值,引用或转换它们的惯用方法是什么
在high != null和之间high > value另一个线程可以这样做high = null,使空检查无效。所以这是预期的行为。
解决这个问题的方法是使用一个不能从外部更改的临时变量:
val cHigh = high
if (cHigh != null) {
if (cHigh > value) {
....
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
414 次 |
| 最近记录: |