Как использовать WHEN в Kotlin для сравнения чисел с операторами <, <=, >, >=?
Проблема: почему ваш код не работает
Вы правы — when в Kotlin действительно мощнее, чем switch в Java, но он не принимает операторы сравнения напрямую в виде < 60 или > 85. В Kotlin when ожидает либо конкретные значения, либо выражения, которые возвращают Boolean. Оператор < сам по себе — это не выражение, а часть условного выражения.
Решение: используйте выражения с аргументом или без
Есть два основных подхода. Первый — передать в when аргумент и использовать in с диапазонами. Второй — использовать when без аргумента, где каждая ветка — это логическое условие.
Способ 1: Диапазоны с in
Самый простой способ для вашей задачи — использовать оператор in с диапазонами. Это работает для любых сравнимых типов:
val score = 85
when (score) {
in Int.MIN_VALUE until 60 -> println("Неудовлетворительно")
in 60..70 -> println("Удовлетворительно")
in 71..85 -> println("Хорошо")
in 86..Int.MAX_VALUE -> println("Отлично")
}
Но это громоздко. Kotlin позволяет использовать .. и until для открытых/закрытых диапазонов. Однако для строгих сравнений (<, >) удобнее второй способ.
Способ 2: when без аргумента (рекомендуется)
Если вы не передаёте аргумент в when, каждая ветка должна быть булевым выражением. Это идеально подходит для сравнений:
val score = 85
when {
score < 60 -> println("Неудовлетворительно")
score in 60..70 -> println("Удовлетворительно")
score in 71..85 -> println("Хорошо")
score > 85 -> println("Отлично")
}
Обратите внимание: score < 60 — это корректное булево выражение. Такой синтаксис работает и для любых других операторов: <=, >=, >, <.
Продвинутые примеры
Вы можете комбинировать условия с помощью && и ||:
val temperature = 25
when {
temperature < 0 -> println("Мороз")
temperature in 0..10 -> println("Холодно")
temperature in 11..20 -> println("Прохладно")
temperature in 21..30 -> println("Тепло")
temperature > 30 -> println("Жарко")
}
Также можно использовать else для всех остальных случаев:
when {
score < 60 -> println("Плохо")
score < 75 -> println("Средне")
score < 90 -> println("Хорошо")
else -> println("Отлично")
}
Когда использовать какой способ?
- С аргументом — когда проверяете конкретные значения (например,
when (x) { 1 -> ... }) или диапазоны черезin. - Без аргумента — когда нужно сложное условие с операторами сравнения, логическими операторами или когда условия независимы.
Оба подхода — идиоматичны для Kotlin. Выбирайте тот, который делает код понятнее.
<<Альтернатива: использование функции сравнения
Если вам не нравится синтаксис when без аргумента, можно создать вспомогательную функцию-расширение для чисел, которая возвращает Comparable результат. Но это уже излишне для простых задач.
Более практичный вариант — использовать compareTo внутри when:
val score = 85
when (score.compareTo(60)) {
-1 -> println("Неудовлетворительно")
0, 1 -> when (score.compareTo(85)) {
-1, 0 -> println("Хорошо")
1 -> println("Отлично")
}
}
Однако этот код сложнее читать. Поэтому для сравнений я рекомендую первый способ — when без аргумента. Он проще и нагляднее, особенно для начинающих.
Ещё один совет: если у вас много веток с диапазонами, рассмотрите использование when с in и константами для границ — это улучшит читаемость:
val FAIL = Int.MIN_VALUE until 60
val GOOD = 71..85
when (score) {
in FAIL -> println("Неуд")
in GOOD -> println("Хорошо")
else -> println("Другое")
}
Главное правило: выбирайте подход, который делает код самодокументируемым. Kotlin даёт гибкость, но не злоупотребляйте ею.