[英]Kotlin check for null twice in if else
我有一個帶有變量datePurchased
的項目,該項目可以為null。 根據購買日期,我會生成一個標簽。 當我檢查datePurchased是否為null時,在else分支中,我仍然必須檢查null。 它說不可能進行智能轉換,因為它是可變屬性。
到目前為止,這是我嘗試過的方法:
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是可變的,這意味着可以更改它。
您的代碼未在任何類型的同步鎖內運行,這意味着另一個線程可能正在同時運行並對其進行修改。
考慮到這一點,可能會發生以下情況:
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()) {
...
}
}
但是最主要的是,您現在需要考慮不可變在應用程序上下文中的真正含義,以及是否真的需要使變量可變。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.