2016-11-17 9 views
1

У меня есть элемент с переменной datePurchased, который может быть пустым. Основываясь на дате покупки, я создаю ярлык. Когда я проверяю, имеет ли datePurchased значение null, в ветке else мне все равно нужно проверить значение null. В нем говорится, что умный литье невозможно, потому что это свойство mutable.Kotlin проверяет значение null дважды в if else

Вот что я пытался до сих пор:

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-impossibleible) – miensol

+0

@miensol Итак, вы предполагаете, что ветка my 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. 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()) { 
     ... 
    } 
} 

Но главное это теперь нужно думать о том, что неизменное на самом деле означает в контексте ваше приложение, и действительно ли вам нужно изменить переменные.

 Смежные вопросы

  • Нет связанных вопросов^_^