2016-11-17 21 views
1

我有一個項目變量datePurchased,它可以爲空。根據購買日期,我生成一個標籤。當我檢查datePurchased是否爲null時,在其他分支中,我仍然需要檢查null。它說聰明的演員是不可能的,因爲它是一個可變的財產。Kotlin檢查空兩次,否則

這裏是我試過到目前爲止:

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      -> { 

     } 
    } 
+4

可能的重複[最好的方式來處理這種情況下,「智能轉換是不可能的」](http://stackoverflow.com/questions/39246249/best-way-to-handle-such-scenario-where-smart- cast-is-imposible) – miensol

+0

@miensol所以,你在暗示我的else分支應該被「包裹」在'?.let'中? –

+0

是的。你可以這樣做:'datePurchased?.let {if(it.isToday())//做點什麼}?:「」' – marstran

回答

3

由於marstran,我結束了這樣的解決方案:

 return datePurchased?.let { 
      when { 
       it.isToday()  -> { 
        "Today" 
       } 
       it.isYesterday() -> { 
        "Yesterday" 
       } 
       else    -> { 
        dateFormat.format(it) 
       } 

      } 
     } ?: "" 
0

如果你有信心,你有沒有數據的比賽中datePurchased成爲null,然後在else分支中加入一個非空的斷言:

if (datePurchased == null) { 
    "" 
} else { 
    datePurchased!!.isToday() 
} 

或者更短,更可靠:

datePurchased?.isToday() ?: "" 
0
  1. 購置日期是可變的,這意味着它可以被改變。

  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()) { 
     ... 
    } 
} 

但更主要的是你現在需要思考什麼一成不變的真正意義的背景下你的應用程序,以及你是否真的需要變量可變。