Использование Boolean? в условном выражении if в Kotlin
Проблема: почему нельзя использовать Boolean? в if
В Kotlin тип Boolean? — это nullable-обёртка, которая может содержать три состояния: true, false и null. Условное выражение if в Kotlin строго типизировано и ожидает только Boolean (non-nullable). Это сделано для безопасности: если бы null автоматически интерпретировался как false, это могло бы привести к неожиданным ошибкам, как в Java с автоупаковкой.
Правильные способы обработки Boolean?
1. Явное сравнение с true (рекомендуемый способ)
Самый простой и читаемый подход — использовать if (isActive == true):
val isActive: Boolean? = null
if (isActive == true) {
println("Активно") // выполнится только если isActive == true
} else {
println("Не активно") // выполнится если false или null
}
Это не костыль, а идиоматичный способ. Код явно показывает, что мы рассматриваем null как "не активно".
2. Использование оператора ?: (Элвис)
Можно привести Boolean? к обычному Boolean со значением по умолчанию:
val isActive: Boolean? = null
if (isActive ?: false) {
println("Активно")
} else {
println("Не активно")
}
Оператор ?: возвращает правую часть, если левая равна null. Здесь null превращается в false.
3. Использование when для трёх состояний
Если вам нужно различать все три состояния (true, false, null):
val isActive: Boolean? = null
when (isActive) {
true -> println("Активно")
false -> println("Не активно")
null -> println("Неизвестно")
}
Этот подход даёт максимальную гибкость, когда null имеет особый смысл (например, "статус не установлен").
4. Использование безопасного вызова с let
val isActive: Boolean? = null
isActive?.let { value ->
if (value) {
println("Активно")
} else {
println("Не активно")
}
} ?: run {
println("isActive == null")
}
Этот вариант избыточен для простых случаев, но может быть полезен в цепочках вызовов.
Рекомендация
- Для простой проверки на
trueс обработкойnullкакfalse— используйтеif (isActive == true). Это наиболее читаемо. - Если
nullдолжен иметь отдельную логику — используйтеwhen. - Избегайте
if (isActive ?: false)в сложных выражениях — это может снизить читаемость.
Главное помнить: Kotlin заставляет вас явно обрабатывать null, что предотвращает множество багов, типичных для Java.
Альтернативный подход: расширение для Boolean?
Если вам часто приходится работать с Boolean? и вы хотите сделать код ещё более выразительным, можно написать простое расширение:
fun Boolean?.orFalse(): Boolean = this ?: false
// Использование:
val isActive: Boolean? = null
if (isActive.orFalse()) {
println("Активно")
} else {
println("Не активно")
}
Или для явного сравнения с true:
fun Boolean?.isTrue(): Boolean = this == true
// Использование:
if (isActive.isTrue()) {
println("Активно")
}
Это особенно удобно, когда Boolean? приходит из внешних источников (база данных, JSON, API). Однако не злоупотребляйте этим — для разовых проверок лучше использовать встроенные средства.
Также помните, что в Kotlin есть аннотация @RecentlyNonNull и @Nullable для совместимости с Java, но в чистом Kotlin-коде расширения — это отличный способ сделать nullable-логику более читаемой.