Тернарный оператор в Kotlin: 5 главных ошибок новичков

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Тернарный оператор в Kotlin: почему его нет и как не наступить на грабли

Если вы пришли в Kotlin из Java, C# или JavaScript, то наверняка хотя бы раз ловили себя на мысли: «Где же мой любимый тернарный оператор условие ? значение1 : значение2?». Спойлер: в Kotlin его нет. И это не баг, а фича. Разработчики языка решили, что классический тернарник — это лишняя сущность, которая только усложняет чтение кода, особенно когда вложенных условий становится больше двух.

Но отсутствие тернарного оператора — не проблема. Kotlin предлагает гораздо более гибкие и безопасные альтернативы. Однако новички (да и опытные разработчики) часто совершают одни и те же ошибки, пытаясь эмулировать привычную конструкцию. В этой статье мы разберём топ-5 ошибок при работе с условными выражениями в Kotlin и покажем, как их избежать. Поехали!

Ошибка №1: Попытка вставить тернарный оператор «в лоб»

Самая распространённая ошибка — написать код в стиле Java:

// ❌ Ошибка: такого синтаксиса в Kotlin нет
val max = (a > b) ? a : b

Kotlin просто не скомпилирует такой код. Вы получите ошибку: Unresolved reference: ?. Многие разработчики впадают в ступор и начинают искать библиотеки или плагины, которые «добавляют» тернарный оператор. Не делайте этого!

Как правильно?

В Kotlin if — это не оператор, а выражение. Оно возвращает значение. Поэтому вместо тернарника используйте обычный if-else:

// ✅ Правильный способ: if как выражение
val max = if (a > b) a else b

Код читается даже легче, чем классический тернарник, особенно если условие сложное. Запомните: if в Kotlin всегда возвращает последнее значение в каждой ветке.

Ошибка №2: Забыть про else при присваивании

Поскольку if — это выражение, оно обязано возвращать значение. Если вы напишете:

// ❌ Ошибка: нет else, компилятор не знает, что возвращать
val result = if (condition) "Yes"

Компилятор выдаст ошибку: All branches of 'if' expression are required to return a value. Это логично: что должно быть в result, если условие ложно? null? Пустая строка? Компилятор не угадывает.

Как правильно?

Всегда добавляйте else:

// ✅ Правильно: обе ветки возвращают значение
val result = if (condition) "Yes" else "No"

Исключение — если вы используете if как оператор (без присваивания). Тогда else не обязателен:

// Операторный if — else не нужен
if (condition) {
    println("Yes")
}

Ошибка №3: Сложные вложенные if-else вместо when

Когда у вас больше двух вариантов, цепочка if-else if-else превращается в «спагетти». Посмотрите на этот ужас:

// ❌ Плохо: вложенные if-else тяжело читать
val status = if (code == 200) "OK"
            else if (code == 404) "Not Found"
            else if (code == 500) "Server Error"
            else "Unknown"

Строчки прыгают, глаза разбегаются. А если добавить ещё пару условий — будет кошмар.

Как правильно?

Используйте when — это аналог switch на стероидах:

// ✅ Отлично: when читается как таблица
val status = when (code) {
    200 -> "OK"
    404 -> "Not Found"
    500 -> "Server Error"
    else -> "Unknown"
}

when в Kotlin тоже является выражением, поэтому может возвращать значение. И он гораздо нагляднее цепочки if-else. Кроме того, when поддерживает сложные условия: диапазоны, типы, произвольные выражения.

// when с диапазоном
val grade = when (score) {
    in 90..100 -> "A"
    in 80..89  -> "B"
    in 70..79  -> "C"
    else       -> "D"
}

Ошибка №4: Игнорирование Elvis-оператора ?: для null-проверок

Новички часто пытаются написать что-то вроде:

// ❌ Плохо: избыточный if для null
val name = if (user != null) user.name else "Guest"

Это работает, но Kotlin предлагает более элегантное решение — Elvis-оператор (?:). Он похож на тернарный, но только для работы с nullable-значениями.

Как правильно?

// ✅ Элегантно: Elvis-оператор
val name = user?.name ?: "Guest"

Разберём по косточкам:

  • user?.name — безопасный вызов: если user == null, то результат null, иначе — user.name.
  • ?: "Guest" — если левая часть null, используем "Guest".

Это кратко, безопасно и читаемо. Запомните: Elvis-оператор — это ваш лучший друг в мире null safety.

Но не путайте его с тернарным! ?: работает только с nullable-значениями, а не с произвольными булевыми условиями. Если вам нужно проверить не на null, а на что-то другое — используйте if-else или when.

Ошибка №5: Использование let и run там, где нужен простой if

Некоторые разработчики, насмотревшись на функциональный стиль, пытаются заменить простой if на цепочки let, also или run. Например:

// ❌ Плохо: избыточная функциональщина
val displayText = someValue?.let {
    if (it > 0) "Positive" else "Non-positive"
} ?: "Null value"

Это работает, но читается тяжело. Зачем так усложнять, если можно написать проще?

Как правильно?

// ✅ Просто и ясно
val displayText = if (someValue != null) {
    if (someValue > 0) "Positive" else "Non-positive"
} else {
    "Null value"
}

Или ещё лучше — вынести логику в отдельную функцию:



                
                

Блоги

Рекомендаций по книгам