Исчерпывающий when
Обрабатывайте все варианты
«Исчерпывающий when» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 4 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.
Охват всех случаев
Исчерпывающий when обрабатывает каждое возможное значение. При использовании в качестве выражения Kotlin требует этого, чтобы результат формировался всегда.
В этом уроке показано, как сделать when исчерпывающим и почему это полезно.
Ветвь «иначе» делает конструкцию исчерпывающей
Для объектов с открытым набором значений, таких как Int, ветвь else охватывает всё, что не перечислено.
Это гарантирует, что конструкция when всегда найдёт подходящий вариант.
fun label(n: Int): String = when (n) {
0 -> "zero"
1 -> "one"
else -> "many"
}
fun main() {
println(label(0))
println(label(5))
}Перечисления обеспечивают полноту
Для перечисления компилятор знает все возможные значения. Перечислите их все — и else можно не указывать.
enum class Direction { NORTH, SOUTH, EAST, WEST }
fun turn(d: Direction): String = when (d) {
Direction.NORTH -> "up"
Direction.SOUTH -> "down"
Direction.EAST -> "right"
Direction.WEST -> "left"
}
fun main() {
println(turn(Direction.EAST))
}Пропущен вариант перечисления
Если в выражении when забыть значение перечисления, компилятор сообщит об ошибке.
Так обнаруживаются ошибки сразу после добавления новой константы перечисления.
enum class Status { ACTIVE, PAUSED, STOPPED }
fun describe(s: Status): String = when (s) {
Status.ACTIVE -> "running"
Status.PAUSED -> "paused"
Status.STOPPED -> "stopped"
}
fun main() {
println(describe(Status.PAUSED))
}Запечатанные классы
Запечатанный класс имеет фиксированный набор подклассов, известных во время компиляции.
Благодаря этому конструкция when может охватить все подтипы без else.
sealed class Shape
class Circle(val r: Double) : Shape()
class Square(val s: Double) : Shape()
fun area(shape: Shape): Double = when (shape) {
is Circle -> 3.14159 * shape.r * shape.r
is Square -> shape.s * shape.s
}
fun main() {
println(area(Square(4.0)))
}Зачем нужна полнота
Исчерпывающая конструкция when превращает пропущенные варианты в ошибки компиляции, а не в незаметные ошибки.
Добавьте новый подкласс или значение перечисления — и компилятор укажет на каждую конструкцию when, которую необходимо обновить.
Для инструкций полнота не обязательна
Если конструкция when используется как инструкция, а не присваивается переменной, она не обязана быть исчерпывающей.
Но для перечислений и запечатанных типов всё равно рекомендуется охватывать все варианты.
enum class Light { RED, GREEN }
fun main() {
val light = Light.RED
when (light) {
Light.RED -> println("stop")
Light.GREEN -> println("go")
}
}Объединение запечатанных классов и классов данных
В запечатанных иерархиях часто используют подклассы — классы данных. Это даёт исчерпывающее сопоставление и умные приведения типов для доступа к свойствам.
sealed class Result
data class Ok(val value: Int) : Result()
data class Err(val message: String) : Result()
fun show(r: Result): String = when (r) {
is Ok -> "ok: " + r.value
is Err -> "error: " + r.message
}
fun main() {
println(show(Ok(42)))
println(show(Err("boom")))
}Ветвь «иначе» как страховка
В конструкцию when для запечатанного типа или перечисления всё ещё можно добавить else, но тогда компилятор перестанет предупреждать о новых вариантах.
Если не указывать else, сохраняется безопасность на этапе компиляции, поэтому для закрытых типов предпочтительнее обходиться без неё.
enum class Coin { HEADS, TAILS }
fun flip(c: Coin): Int = when (c) {
Coin.HEADS -> 1
Coin.TAILS -> 0
}
fun main() {
println(flip(Coin.HEADS))
}Логический тип и объекты с закрытым набором значений
У типа Boolean всего два значения, поэтому при перечислении обоих конструкция when становится исчерпывающей без else.
fun yesNo(flag: Boolean): String = when (flag) {
true -> "yes"
false -> "no"
}
fun main() {
println(yesNo(true))
println(yesNo(false))
}Объединяем всё вместе
Исчерпывающая конструкция when означает, что охвачены все варианты:
elseохватывает объекты с открытым набором значений, такие какInt- Перечисления, запечатанные классы и
Booleanмогут быть исчерпывающими безelse - При добавлении новых вариантов компилятор указывает на пропущенные
sealed class Event
object Start : Event()
object Stop : Event()
fun handle(e: Event): String = when (e) {
is Start -> "starting"
is Stop -> "stopping"
}
fun main() {
println(handle(Start))
println(handle(Stop))
}Быстрая проверка
Проверьте, насколько хорошо Вы поняли исчерпывающие конструкции when.
Итоги
Вы научились делать конструкцию when исчерпывающей:
elseобрабатывает объекты с открытым набором значений- Перечисления, запечатанные классы и
Booleanможно полностью охватить - Проверки во время компиляции обнаруживают пропущенные варианты
На этом завершается курс «Выражения выбора и умные приведения типов».
Изучай Kotlin с ИИ-репетитором — бесплатно
Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.
- Курсы
- 51
- Уроки
- 203
Часто задаваемые вопросы
Урок «Исчерпывающий when» бесплатный?
Да — полный текст урока «Исчерпывающий when» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Исчерпывающий when»?
Обрабатывайте все варианты Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 4 из 4.
Сколько времени занимает урок «Исчерпывающий when»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- when как выражение
- Умные приведения типов
- Операторы is и as
- Исчерпывающий when