【问题标题】:Non-null assert is needed even after checking is not null in kotlin即使在 kotlin 中检查不为空,也需要非空断言
【发布时间】:2018-08-06 00:13:43
【问题描述】:

我在 android studio 的 Kotlin 中有这段代码:

result.put(REGISTER_DATE, if (activityData.registerDate == null) -1 else activityData.registerDate.totalDays)

如您所见,我检查了 registerDate 不为空,但我必须在 activityData.registerDate 之后放置非空断言以消除空错误:

result.put(REGISTER_DATE, if (activityData.registerDate == null) -1 else activityData.registerDate!!.totalDays)

这是 Kotlin 中的错误还是与 Android Studio 有关?

【问题讨论】:

  • 你不应该在这样的函数调用中嵌套 if else 语句。使用 elvis 运算符或将条件提取到变量中,以提高可读性

标签: android kotlin


【解决方案1】:

这不是错误,smart casting 在这种情况下不起作用。您可以使用Elvis Operator 将代码修复为更好的解决方案:

result.put(REGISTER_DATE, activityData.registerDate?.totalDays ?: -1)

表达式activityData.registerDate?.totalDays 的计算结果为totalDaysnull,以防安全运算符链中访问的任何值也是null。如果表达式的计算结果为 null,Elvis Operator 将负责提供您的默认值 -1

【讨论】:

    【解决方案2】:

    这是 Kotlin 中的错误还是与 Android Studio 有关?

    两者都不是。 activity.registerDate 是对象的可变可为空属性,因此它可以(理论上)随时由另一个线程更改。 Kotlin 编译器没有足够的知识来证明该属性的值在您第二次加载时不会改变这一无可争辩的事实。

    避免这种情况的典型方法是只加载一次属性,将其捕获到局部变量中。在您展示的特定情况下,您只需要 Elvis 运算符:

    activityData.registerDate?.totalDays ?: -1
    

    【讨论】:

      【解决方案3】:

      您可能正在检查可变属性 (var)。并且由于可能的并发问题,Kotlin 编译器不执行智能转换为非空值。

      顺便说一句,还有另一种 Kotlin 方法可以进行此类检查:

       result.put(REGISTER_DATE, activityData.registerDate?.totalDays ?: -1)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多