Разрешение условия, которое требует логического значения, но найдено логическое значение?

#kotlin

#kotlin

Вопрос:

Kotlin 1.4.0

Разрешение условия, которое требует логического значения, но найдено логическое значение?

У меня есть следующий код:

 detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode?.run { this != ZERO }
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}
  

Здесь я получаю сообщение об ошибке, в котором говорится required Boolean found Boolean?

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

Это работает путем удаления оператора безопасного вызова

 detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode.run { this != ZERO }
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}
  

В приведенном выше примере не произойдет ли сбой, если почтовый индекс действительно равен нулю?

Это код, который я использовал, когда проверял значение null, а затем оценивал второе условие:

 detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
        postcode != null amp;amp; postcode != ZERO            
}?.also { postcode ->
        view.editTextPostcode.setText(postcode)
}
  

Как @Steyrix заметил в своем комментарии, если почтовый индекс действительно равен нулю, то оценка условия не выполняется.

Это обновление, которое оценит условие и вернет истинное логическое значение. Если почтовый индекс равен нулю, то он вернет false

 detailList.firstOrNull()?.postCode.takeIf { postcode: String? ->
    postcode?.run {
        postcode != ZERO
    } ?: false         
}?.also { postcode ->
    view.editTextPostcode.setText(postcode)
}
  

Комментарии:

1. Разве в первом случае оно не преобразуется в ненулевое значение, потому что вы явно объявляете его как переменную с нулевым типом? Если почтовый код может быть нулевым, не может быть вычисления логического выражения, поэтому не может быть логического значения.

2. Это имеет смысл в том, что вы сказали, и обновили мой вопрос возможным решением. Возвращаемое логическое значение может быть возвращено только в том случае, если почтовый индекс не равен нулю. если почтовый индекс равен null, оценка не выполняется. Однако, только один вопрос. Если почтовый индекс равен нулю, он пропустит оценку, в таком случае почему IDE говорит «требуется», Boolean but found Boolean? я бы подумал, что он нашел Unit , поскольку в качестве последнего состояния ничего не возвращается? Спасибо

3. Это происходит потому, что выполнение типизированного метода для экземпляра с нулевым значением вернет null, если экземпляр на самом деле равен null. Например. object?.intMethod вернет null как Int? . object?.boolMethod вернет значение null как Boolean? . Поскольку нет единицы с нулевым значением, компилятор определяет тип как возвращаемый тип метода с нулевым значением.

4. @Steyrix можете ли вы создать это в качестве ответа, чтобы я мог пометить этот вопрос как решенный

5. да, конечно. Я опубликовал ответ

Ответ №1:

Отвечая на исходный вопрос:

postCode на самом деле не выполняется интеллектуальное приведение к ненулевому типу, поскольку оно явно объявлено как переменная с нулевым типом. Вычисление логического выражения не произойдет, когда postCode будет равно null. Поскольку не может быть никакой оценки, не может быть никакого Boolean но Boolean? вместо этого.

Причина, по которой возвращаемый тип не выполняется Unit , заключается в том, что выполнение типизированного метода в экземпляре с нулевым значением возвращает null, если экземпляр также имеет значение null. Однако значение null может представлять разные типы в зависимости от типа возвращаемого метода.

Например. при наличии экземпляра с нулевым значением object :

Поскольку экземпляр равен нулю, вызывающие методы / поля-члены будут возвращать значение null. object?.intMethod() вернет null как Int? и object?.boolMethod() вернет null как Boolean?

В вашем случае компилятор определяет фактический тип возвращаемого значения takeIf как тип возвращаемого значения с нулевым значением run , который является Boolean? , поскольку последний метод возвращает результат вычисления логического выражения.