type | layout | category | title | url |
---|---|---|---|---|
doc |
reference |
Syntax |
Операторы перехода |
В Kotlin определено три оператора перехода:
- return по умолчанию производит возврат из ближайшей окружающей его функции или анонимной функции
- break завершает выполнение цикла
- continue продолжает выполнение цикла со следующего его шага, без обработки оставшегося кода текущей итерации
Любое выражение в Kotlin может быть помечено меткой label.
Метки имеют идентификатор в виде знака @
. Например: метки abc@
, fooBar@
являются корректными
(см. грамматика). Для того, чтобы пометить выражение, мы просто ставим метку перед ним:
loop@ for (i in 1..100) {
// ...
}
Теперь мы можем уточнить значения операторов break или continue с помощью меток:
loop@ for (i in 1..100) {
for (j in 1..100) {
if (...)
break@loop
}
}
Оператор break, отмеченный @loop
, переводит выполнение кода к той его части, которая находится сразу после соответствующей метки loop@
.
Оператор continue продолжает цикл со следующей его итерации.
В Kotlin функции могут быть вложены друг в друга с помощью анонимных объектов, локальных функций (ориг.:local functions) и function literals. Подходящий return позволит вернуться из внешней функции. Одним из самых удачных применений этой синтаксической конструкции служит возврат из лямбда-выражения. Подумайте над этим утверждением, читая данный пример:
fun foo() {
ints.forEach {
if (it == 0) return
print(it)
}
}
Опертор return возвращается из ближайшей функции, в нашем случае foo
.
(Обратите внимание, что такой местный возврат поддерживается только лямбда-выражениями, переданными инлайн-функциям.) Если нам надо вернуться из лямбда-выражения, к оператору стоит поставить метку и тем самым сделать уточнение для ключевого слова return:
fun foo() {
ints.forEach lit@ {
if (it == 0) return@lit
print(it)
}
}
Теперь он возвращается только из лямда-выражения. Зачастую намного более удобно указывать метки неявно: такие метки имеют такое же имя, как и функция, к которой относится лямбда.
fun foo() {
ints.forEach {
if (it == 0) return@forEach
print(it)
}
}
Возможно также использование анонимной функции в качестве альтернативы лямбда-выражениям. Оператор return вовзращается из самой анонимной функции.
fun foo() {
ints.forEach(fun(value: Int) {
if (value == 0) return
print(value)
})
}
При возвращении значения парсер отдаёт предпочтение специализированному возврату, типа
return@a 1
что значит "верни 1
в метке @a
, а не "верни выражение с меткой (@a 1)
".