簡體   English   中英

Kotlin在其他情況下兩次檢查null

[英]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() ?: ""
  1. datePurchased是可變的,這意味着可以更改它。

  2. 您的代碼未在任何類型的同步鎖內運行,這意味着另一個線程可能正在同時運行並對其進行修改。

考慮到這一點,可能會發生以下情況:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM