Как реализовать switch-case в Kotlin? Альтернативы и примеры
Полное руководство по when в Kotlin: замена switch-case
Да, вы правы — в Kotlin нет оператора switch. Вместо него используется гораздо более мощная конструкция when. Она может работать и как оператор (просто выполняет блок кода), и как выражение (возвращает значение). Давайте разберём все сценарии.
1. Базовая замена switch-case
Вот как переписать ваш пример с днями недели:
fun main() {
val day = 3
val dayName = when (day) {
1 -> "Понедельник"
2 -> "Вторник"
3 -> "Среда"
4 -> "Четверг"
5 -> "Пятница"
else -> "Выходной"
}
println(dayName) // Выведет: Среда
}
Обратите внимание: break не нужен — Kotlin сам выходит из ветки после выполнения. else заменяет default.
2. Несколько значений в одной ветке
Если нужно объединить несколько вариантов, используйте запятую:
fun isWeekend(day: Int): String {
return when (day) {
1, 2, 3, 4, 5 -> "Будний день"
6, 7 -> "Выходной"
else -> "Неверный день"
}
}
3. Проверка типа объекта
Это одна из самых мощных возможностей when — проверка типа с умным приведением (smart cast):
fun describe(obj: Any): String {
return when (obj) {
is String -> "Строка длиной ${obj.length}" // obj автоматически приведён к String
is Int -> if (obj > 0) "Положительное число" else "Число <= 0"
is Boolean -> "Логическое значение: $obj"
else -> "Неизвестный тип"
}
}
fun main() {
println(describe("Привет")) // Строка длиной 6
println(describe(42)) // Положительное число
println(describe(true)) // Логическое значение: true
}
4. When как выражение (возврат значения)
Если вы используете when как выражение, ветка else обязательна, если компилятор не может доказать, что все возможные случаи покрыты:
val grade = 85
val result = when {
grade >= 90 -> "Отлично"
grade >= 75 -> "Хорошо"
grade >= 60 -> "Удовлетворительно"
else -> "Неудовлетворительно"
}
println(result) // Хорошо
Обратите внимание: здесь нет аргумента у when — мы используем произвольные условия (булевы выражения).
5. When без аргумента (произвольные условия)
Это аналог цепочки if-else if, но более читаемый:
fun classifyNumber(x: Int) {
when {
x < 0 -> println("Отрицательное")
x == 0 -> println("Ноль")
x > 0 && x % 2 == 0 -> println("Положительное чётное")
x > 0 && x % 2 != 0 -> println("Положительное нечётное")
}
}
6. Проверка на вхождение в диапазон (range)
fun checkAge(age: Int): String {
return when (age) {
in 0..12 -> "Ребёнок"
in 13..17 -> "Подросток"
in 18..65 -> "Взрослый"
else -> "Пожилой"
}
}
Важные моменты:
- When с аргументом — проверяет равенство аргумента с константами (или другими значениями).
- When без аргумента — просто выполняет первую истинную ветку (как if-else if).
- When как выражение — обязательно должен быть else, если не все случаи покрыты.
- Smart cast — после проверки
isвы можете использовать свойства типа без явного приведения.
Таким образом, when полностью заменяет switch-case и даёт гораздо больше возможностей. Привыкайте использовать его — это идиоматичный способ в Kotlin.
<<Альтернативный подход: использование when с sealed классами
Когда вы работаете с ограниченным набором типов (например, состояниями или командами), рекомендую использовать sealed class вместе с when. Это даёт компиляторную проверку полноты ветвей — вам не нужен else, если вы перечислили все подтипы.
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val message: String) : Result()
object Loading : Result()
}
fun handleResult(result: Result): String = when (result) {
is Result.Success -> "Успех: ${result.data}"
is Result.Error -> "Ошибка: ${result.message}"
Result.Loading -> "Загрузка..."
// else не нужен — все варианты покрыты
}
Если вы добавите новый подтип в sealed class, компилятор укажет, где нужно добавить ветку when. Это делает код безопаснее и предотвращает забытые сценарии. Такой подход часто используется в архитектуре приложений (например, в MVVM для обработки состояний UI).
Также для простых случаев можно использовать when с лямбдами или функции высшего порядка, но это уже экзотика. Главное — запомните: when — это мощный инструмент, который заменяет не только switch, но и многие цепочки if-else.