Конструкция when проверяет значение некоторого объекта и в зависимости от его значения выполняет тот или иной код. Конструкция when аналогична конструкции switch в других языках. Формальное определение:
when(объект){ значение1 -> действия1 значение2 -> действия2 значениеN -> действияN }
Если значение объекта равно одному из значений в блоке кода when, то выполняются соответствующие действия, которые идут после оператора ->
после соответствующего значения.
Например:
fun main() { val isEnabled = true when(isEnabled){ false -> println("isEnabled off") true -> println("isEnabled on") } }
Здесь в качестве объекта в конструкцию when
передается переменная isEnabled
. Далее ее значение по порядку сравнивается со значениями в
false
и true
. В данном случае переменная isEnabled
равна true
, поэтому будет выполняться код
println("isEnabled on")
В примере выше переменная isEnabled имела только два возможных варианта: true и false. Однако чаще бывают случаи, когда значения в блоке when
не покрывают все возможные
значения объекта. Дополнительное выражение else позволяет задать действия, которые выполняются, если
объект не соответствует ни одному из значений. Например:
val a = 30 when(a){ 10 -> println("a = 10") 20 -> println("a = 20") else -> println("неопределенное значение") }
То есть в данном случае если переменная a равна 30, поэтому она не соответствует ни одному из значений в блоке when. И соответственно будут выполняться инструкции из выражения else.
Если надо, чтобы при совпадении значений выполнялось несколько инструкций, то для каждого значения можно определить блок кода:
var a = 10 when(a){ 10 -> { println("a = 10") a *= 2 } 20 -> { println("a = 20") a *= 5 } else -> { println("неопределенное значение")} } println(a)
Можно определить одни и те же действия сразу для нескольких значений. В этом случае значения перечисляются через запятую:
val a = 10 when(a){ 10, 20 -> println("a = 10 или a = 20") else -> println("неопределенное значение") }
Также можно сравнивать с целым диапазоном значений с помощью оператора in:
val a = 10 when(a){ in 10..19 -> println("a в диапазоне от 10 до 19") in 20..29 -> println("a в диапазоне от 20 до 29") !in 10..20 -> println("a вне диапазона от 10 до 20") else -> println("неопределенное значение") }
Если оператор in позволяет узнать, есть ли значение в определенном диапазоне, то связка операторов !in позволяет проверить отсутствие значения в определенной последовательности.
Выражение в when также может сравниваться с динамически вычисляемыми значениями:
fun main() { val a = 10 val b = 5 val c = 3 when(a){ b - c -> println("a = b - c") b + 5 -> println("a = b + 5") else -> println("неопределенное значение") } }
Так, в данном случае значение переменной a
сравнивается с результатом операций b - c
и b + 5
.
Кроме того, when также может может принимать динамически вычисляемый объект:
fun main() { val a = 10 val b = 20 when(a + b){ 10 -> println("a + b = 10") 20 -> println("a + b = 20") 30 -> println("a + b = 30") else -> println("Undefined") } }
Можно даже определять переменные, которые будут доступны внутри блока when
:
fun main() { val a = 10 val b = 26 when(val c = a + b){ 10 -> println("a + b = 10") 20 -> println("a + b = 20") else -> println("c = $c") } }
Причем в принципе нам необязатльно вообще сравнивать значение какого-либо объекта. Конструкция when
аналогично конструкции if..else
просто может поверять
набор условий и если одно из условий возвращает true
, то выполнять соответствующий набор действий:
fun main() { val a = 15 val b = 6 when{ (b > 10) -> println("b больше 10") (a > 10) -> println("a больше 10") else -> println("и a, и b меньше или равны 10") } }
Как и if
конструкция when
может возвращать значение. Возвращаемое значение указывается после оператора ->
:
fun main(){ val day = 2 var dayOfweek = when (day) { 1 -> "Monday" 2 -> "Tuesday" 3 -> "Wednesday" 4 -> "Thursday" else -> "Unknown" } println(dayOfweek) // Tuesday }
Здесь в зависимости от значения переменной day в другой переменной - dayOfweek окажется та или иная строка.
Другой пример:
val sum = 1000 val rate = when(sum){ in 100..999 -> 10 in 1000..9999 -> 15 else -> 20 } println(rate) // 15
Таким образом, если значение переменной sum располагается в определенном диапазоне, то возвращается то значение, которое идет после стрелки.