Условный оператор 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() {
    var s = readLine()
 
    when {
        s == "Hello" -> {
            s = "Hello World"
            println(s)
        }
        s == "Hi" -> {
            s = "Hi Bro"
            println(s)
        }
        else -> {
            println("Error")
        }
    }
}

В примере выше значение переменной s в каждой ветке проверяется на равенство только одному значению, а не на вхождение в какое-то множество. В таких случаях оператор when следует использовать как аналог оператора switch (переключатель) в других языках. При этом проверяемая переменная выносится в заголовок конструкции и заключается в круглые скобки.

fun main() {
    var s = readLine()
 
    when (s) {
        "Hello" -> {
            s = "Hello World"
            println(s)
        }
        "Hi" -> {
            s = "Hi Bro"
            println(s)
        }
        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, 52 -> point = 4
        else -> point = 0
    }
 
    println(point)
}

Логическое выражение in 0..30 проверяет входит ли значение n в диапазон чисел от 0 до 30 включительно. Полная запись (не в контексте выноса n в заголовок оператора when) выглядела бы так: n in 0..30. Подобные выражение возвращают либо true, либо false.

В двух первых ветках оператора when мы группируем по два диапазона через запятую. Достаточно, чтобы число входило в какой-то один диапазон, чтобы выполнилось тело ветки. В третьей ветке для наглядности мы перечислили значения через запятую, однако можно было бы записать в виде проверки на вхождение в диапазон – in 48..52.

Также как if-else в Kotlin условный оператор when – вовсе не оператор, а выражение, возвращающее результат. В последнем примере во всех ветках мы присваиваем одной и той же переменной – point. Это присвоение можно вынести за пределы when.

IntelliJ IDEA может сделать это за вас. Для этого необходимо установить курсор в слово when. Появится "лампочка", кликнув на которую следует выбрать "Lift assignment out of 'when'" – вынести присвоение за when.

Вынос присвоения за оператор when в Kotlin

Программа примет такой вид:

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, 52 -> 4
        else -> 0
    }
 
    println(point)
}

Поскольку when возвращает то, что возвращает последнее выражение тела ветки, которая была исполнена, а во всех ветках это целое число, то это число присваивается переменной point.

Практическая работа:

Напишите программу, которая генерирует случайное число от 32 до 122 включительно. Потом преобразовывает число в символ, а дальше проверяет что это – цифра, буква или все остальное. Выводит соответствующее сообщение. В программе следует использовать такие функции-методы как toChar(), isDigit() и isLetter().

PDF-версия курса с ответами к практическим работам

Приложение для Android "Kotlin. Курс"