Условный оператор when
С помощью if-else можно реализовать не только двухходовое ветвление. Для множественного ветвления в одну из веток, обычно else
, вкладывают внутренний блок if-else. Однако современные языки программирования нередко предлагают более удобный способ решения данной задачи. В случае Kotlin для этого используется оператор when
.
import kotlin.random.Random fun main() { val a = Random.nextInt(-2, 3) when { a > 0 -> println("+") a < 0 -> println("-") else -> println("0") } }
В примере у оператора when
три ветки. Каждая начинается с логического выражения – условия. Если первое (a > 0
) возвращает истину, то будет выполнена команда после стрелки ->
. Если возвращает ложь, то поток выполнения программы проверяет второе логическое выражение и так далее. Тело ветки else
выполняется только тогда, когда ни одно условие до него не сработало.
В нашем конкретном случае вместо else
может быть условие a == 0
. Программа будет работать также.
Тело каждой ветки может состоять не из одной команды, а из нескольких. Тогда его заключают в фигурные скобки.
fun main() { val s = readln() when { s == "Hello" -> { print(s) println(" World") } s == "Hi" -> { print(s) println(" user") } else -> { println("Error") } } }
В примере выше значение переменной s в каждой ветке проверяется на равенство только одному значению, а не на вхождение в какое-то множество. В таких случаях оператор when
следует использовать как аналог оператора switch
(переключатель) в других языках. При этом проверяемая переменная выносится в заголовок конструкции и заключается в круглые скобки.
fun main() { val s = readln() when (s) { "Hello" -> { print(s) println(" World") } "Hi" -> { print(s) println(" user") } else -> { println("Error") } } }
Понимать это следует так. Когда s равна "Hello", выполнить тело первой ветки, когда "Hi" – второй, во всех остальных случаях – третьей.
В Kotlin, если when
используется как переключатель, не обязательно, чтобы в заголовках веток стояли одиночные литералы. Значений может быть несколько, перечисленных через запятую, или там может находиться логическое выражение.
import kotlin.random.Random fun main() { val n = Random.nextInt(100) val point: Int when (n) { in 0..30, in 71..100 -> point = 1 in 31..47, in 52..70 -> point = 2 48, 49, 50, 51 -> point = 4 else -> point = 0 } println(point) }
Логическое выражение in 0..30
проверяет входит ли значение n в диапазон чисел от 0 до 30 включительно. Полная запись (не в контексте выноса n в заголовок оператора when
) выглядела бы так: n in 0..30
. Подобные выражение возвращают либо true
, либо false
.
В двух первых ветках оператора when
мы группируем по два диапазона через запятую. Достаточно, чтобы число входило в какой-то один диапазон, чтобы выполнилось тело ветки. В третьей ветке для наглядности мы перечислили значения через запятую, однако можно было бы записать в виде проверки на вхождение в диапазон – in 48..51
.
Также как if-else в Kotlin условный оператор when
– вовсе не оператор, а выражение, возвращающее результат. В последнем примере во всех ветках мы присваиваем одной и той же переменной – point. Это присвоение можно вынести за пределы when
.
IntelliJ IDEA может сделать это за вас. Для этого необходимо установить курсор в слово when
. Появится "лампочка", кликнув на которую следует выбрать "Lift assignment out of 'when'" – вынести присвоение за when
.
Программа примет такой вид:
import kotlin.random.Random fun main() { val n = Random.nextInt(100) val point: Int point = when (n) { in 0..30, in 71..100 -> 1 in 31..47, in 52..70 -> 2 48, 49, 50, 51 -> 4 else -> 0 } println(point) }
Поскольку when
возвращает то, что возвращает последнее выражение тела ветки, которая была исполнена, а во всех ветках это целое число, то это число присваивается переменной point.
Следующим шагом может быть поднятие операции присвоения переменной point к ее объявлению:
Практическая работа:
Напишите программу, которая генерирует случайное число от 32 до 122 включительно. Потом преобразовывает число в символ, а дальше проверяет что это – цифра, буква или все остальное. Выводит соответствующее сообщение. В программе следует использовать такие функции-методы как toChar()
, isDigit()
и isLetter()
.
PDF-версия курса с ответами к практическим работам