为什么在nullcheck

时间:2017-08-10 08:11:15

标签: kotlin

我正在尝试代码的出现,并希望在第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

这是一个错误吗?我做错了吗?

3 个答案:

答案 0 :(得分:6)

由于您将high定义为var,因此它是可变的。即使在此之前有明确的空检查,也无法保证变量不为null。

Official explanation

  

请注意,当编译器无法保证变量在检查和使用之间无法更改时,智能强制转换不起作用。更具体地说,智能演员表适用于以下规则:

     
      
  • 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 != nullhigh > 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