Конструкция when в Kotlin — это мощный инструмент для управления потоком выполнения программы, пришедший на смену традиционному switch-case из Java. when был введён для увеличения выразительности, сокращения boilerplate-кода и повышения безопасности типов.
В Java конструкция switch-case ограничена только определёнными типами (enum, int, String). В отличие от Java, разработчики Kotlin стремились упростить условные ветвления, сделав их более выразительными и безопасными.
Ограничения switch-case в Java затрудняют расширение и сопровождаемость кода, особенно при работе с коллекциями, сравнением диапазонов или обработкой различных типов.
Конструкция when в Kotlin универсальна: она работает как выражение (может возвращать значение), поддерживает проверки условий, диапазонов, отдельных значений, типов и комбинирование условий.
fun describe(obj: Any): String = when (obj) { 1 -> "One" in 2..10 -> "From two to ten" is String -> "String with length ${obj.length}" else -> "Unknown" } val res1 = describe(1) // "One" val res2 = describe(5) // "From two to ten" val res3 = describe("Kotlin") // "String with length 6" val res4 = describe(42.0) // "Unknown"
Может ли when использоваться без аргумента?
Да, when может быть использован как замена длинной цепочки if-else, если не требуется проверять значение конкретной переменной.
when { x < 0 -> println("Negative") x == 0 -> println("Zero") else -> println("Positive") }
Обязателен ли блок else в конструкции when?
Блок else не обязателен, если обработаны все возможные случаи, например, для enum или sealed class. Но если есть вероятность некрытого случая, else обязателен для избежания ошибок времени компиляции.
sealed class Fruit object Apple : Fruit() object Pear : Fruit() fun check(f: Fruit): String = when (f) { Apple -> "It's an apple" Pear -> "It's a pear" // Нет блока else, и компилятор не ругается — все варианты учтены }
Можно ли в when использовать несколько значений в одной ветке?
Да, несколько значений можно объединять через запятую.
when (value) { 0, 1 -> println("Zero or One") else -> println("Other") }
В платежной системе switch-case используется для определения статуса операции. При добавлении нового типа статуса забыли обновить switch. Необработанный статус приводит к silent-error.
Плюсы:
Минусы:
В Kotlin используется sealed class для статусов и конструкция when для их обработки. При добавлении нового статуса компилятор требует добавить обработку нового случая.
Плюсы:
Минусы: