Spec-Zone.ru › Kotlin 1.4

Управление потоком: if, when, for, while

Выражение if

В Kotlin if является выражением, т. е. возвращает значение. Поэтому нет оператора тернарного условия (условие ? тогда : иначе), потому что обычное if отлично справляется с этой ролью.

// Traditional usage 
var max = a 
if (a < b) max = b

// With else 
var max: Int
if (a > b) {
    max = a
} else {
    max = b
}
 
// As expression 
val max = if (a > b) a else b

Ветви if могут быть блоками, и последнее выражение является значением блока:

val max = if (a > b) {
    print("Choose a")
    a
} else {
    print("Choose b")
    b
}

Если вы используете if как выражение, а не как оператор (например, для возврата его значения или присваивания его переменной), выражение должно иметь ветвь else.

См. грамматику для if.

Выражение when

Выражение when заменяет оператор switch в языках семейства C. В простейшем виде оно выглядит так:

when (x) {
    1 -> print("x == 1")
    2 -> print("x == 2")
    else -> { // Note the block
        print("x is neither 1 nor 2")
    }
}

Выражение when последовательно сопоставляет свой аргумент со всеми ветвями, пока не будет удовлетворено условие какой-либо ветви. when может использоваться как выражение или как оператор. Если оно используется как выражение, значение выполненной ветви становится значением всего выражения. Если оно используется как оператор, значения отдельных ветвей игнорируются. (Точно так же, как с if, каждая ветвь может быть блоком, и ее значением является значение последнего выражения в блоке.)

Ветвь else выполняется, если ни одно из других условий ветвей не выполняется. Если when используется как выражение, ветвь else является обязательной, если компилятор не может доказать, что все возможные случаи покрываются условиями ветвей (например, с элементами класса enum и подтипами класса sealed).

Если многие случаи должны обрабатываться одинаково, условия ветвей можно объединить запятыми:

when (x) {
    0, 1 -> print("x == 0 or x == 1")
    else -> print("otherwise")
}

В качестве условий ветвей можно использовать произвольные выражения (не только константы):

when (x) {
    parseInt(s) -> print("s encodes x")
    else -> print("s does not encode x")
}

Также можно проверить, находится ли значение в диапазоне или коллекции с использованием in или !in:

when (x) {
    in 1..10 -> print("x is in the range")
    in validNumbers -> print("x is valid")
    !in 10..20 -> print("x is outside the range")
    else -> print("none of the above")
}

Еще один вариант — проверить, является ли значение определенного типа с помощью is или !is. Обратите внимание, что из-за умных преобразований типов можно получить доступ к методам и свойствам типа без дополнительных проверок.

fun hasPrefix(x: Any) = when(x) {
    is String -> x.startsWith("prefix")
    else -> false
}

Выражение when также может использоваться как замена цепочки if-else if. Если аргумент не указан, условия ветвей являются просто булевыми выражениями, и ветвь выполняется, когда ее условие истинно:

when {
    x.isOdd() -> print("x is odd")
    y.isEven() -> print("y is even")
    else -> print("x+y is even.")
}

Начиная с Kotlin 1.3, можно захватить предмет when в переменной, используя следующий синтаксис:

fun Request.getBody() =
        when (val response = executeRequest()) {
            is Success -> response.body
            is HttpError -> throw HttpException(response.status)
        }

Область действия переменной, введенной в предмет when, ограничена телом when.

См. грамматику для when.

Циклы for

Цикл for перебирает всё, что предоставляет итератор. Это эквивалентно циклу foreach в языках типа C#. Синтаксис следующий:

for (item in collection) print(item)

Тело может быть блоком.

for (item: Int in ints) {
    // ...
}

Как уже упоминалось, for перебирает всё, что предоставляет итератор, т. е.

  • имеет член- или расширенный-метод iterator(), тип возврата которого
    • имеет член- или расширенный-метод next(), и
    • имеет член- или расширенный-метод hasNext(), возвращающий Boolean.

Все эти три функции должны быть помечены как operator.

Для перебора диапазона чисел используйте выражение диапазона:

fun main() {
//sampleStart
    for (i in 1..3) {
        println(i)
    }
    for (i in 6 downTo 0 step 2) {
        println(i)
    }
//sampleEnd
}

Цикл for по диапазону или массиву компилируется в цикл на основе индексов, который не создаёт объект итератора.

Если вы хотите перебрать массив или список с индексом, можно сделать это так:

fun main() {
val array = arrayOf("a", "b", "c")
//sampleStart
    for (i in array.indices) {
        println(array[i])
    }
//sampleEnd
}

В качестве альтернативы можно использовать функцию библиотеки withIndex:

fun main() {
    val array = arrayOf("a", "b", "c")
//sampleStart
    for ((index, value) in array.withIndex()) {
        println("the element at $index is $value")
    }
//sampleEnd
}

См. грамматику для for.

Циклы while

Циклы while и do..while работают как обычно

while (x > 0) {
    x--
}

do {
    val y = retrieveData()
} while (y != null) // y is visible here!

См. грамматику для while.

Прерывание и продолжение циклов

Kotlin поддерживает традиционные операторы break и continue в циклах. См. Возвращение и переходы.

© 2010–2020 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/reference/control-flow.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API