2016-11-17 11 views
1

変数datePurchasedのアイテムがありますが、これにはnullを指定できます。購入日に基づいて、ラベルを生成します。 datePurchasedがnullであるかどうかをチェックすると、elseブランチでもnullをチェックする必要があります。スマートキャストは不可能だと言われています。他の場合はKotlinがnullを2回確認します

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-キャストが可能です) – 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

あなたはdatePurchasednullなったはデータのレースを持っていない自信がある場合は、elseブランチにnull以外のアサーションを追加します:

ここ

は、私がこれまで試したものです

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

たり短くし、より信頼性:

datePurchased?.isToday() ?: "" 
0
  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 datePurchased = datePurchased 

if (datePurchased == null) { 
    ... 
} else { 

    // datePurchased val cannot have been changed, compiler can guarantee safety 

    if (datePurchased.isToday()) { 
     ... 
    } 
} 

をしかし、主なものは、あなたが今、本当にの文脈において不変のものについて考える必要がありますあなたのアプリケーションと、実際に変数を変更可能にする必要があるかどうかを確認します。

関連する問題