否则,Kotlin检查两次null
我有一个variablesdatePurchased
的项目,可以为null。 根据购买日期,我生成一个标签。 当我检查datePurchased是否为空,否则我仍然必须检查为空。 它说聪明的演员是不可能的,因为这是一个可变的财产。
以下是我迄今为止所尝试的:
if (datePurchased == null) { "" } else { if (datePurchased.isToday()) {//error here } } when { datePurchased == null -> { } datePurchased.isToday() -> {//smart cast bla bla mutable bla bla datePurchased?.isToday() -> {//expected Boolean, got Boolean? datePurchased?.isToday()?:false -> {//all good, but does not look nice, since datePurchased can't be null here } else -> { } }
感谢marstran,我结束了这样的解决方案:
return datePurchased?.let { when { it.isToday() -> { "Today" } it.isYesterday() -> { "Yesterday" } else -> { dateFormat.format(it) } } } ?: ""
如果你确信你没有数据竞争,那么在哪个datePurchased
变为null
,然后在else
分支中添加一个非null断言:
if (datePurchased == null) { "" } else { datePurchased!!.isToday() }
或者更短,更可靠:
datePurchased?.isToday() ?: ""
-
datePurchased是可变的,这意味着它可以改变。
-
您的代码不在任何types的同步锁中运行,这意味着另一个线程可能会同时运行并修改它。
考虑到这一点,以下是可能的:
if (datePurchased == null) { ... } else { // another thread comes in here and changes datePurchased=null if (datePurchased.isToday()) { // Null Pointer Exception! ... } }
你可能没有线程这样做,但编译器不知道。 它玩起来很安全,并说你不能这样做。 大概有98%的时间是错误的,但其他2%则强迫你考虑你的代码在并发环境中的表现。
一个解决方案是简单地使用一个不能在新线程中改变的本地val:
val datePurchased = datePurchased if (datePurchased == null) { ... } else { // datePurchased val cannot have been changed, compiler can guarantee safety if (datePurchased.isToday()) { ... } }
但主要的是,你现在需要考虑在你的应用程序的上下文中不可变的真正含义,以及你是否真的需要variables可变。