Spec-Zone.ru › Kotlin 2

Возвраты и переходы

В Kotlin есть три структурных выражения перехода:

  • return по умолчанию возвращает управление из ближайшей охватывающей функции или анонимной функции.

  • break завершает ближайший охватывающий цикл.

  • continue переходит к следующему шагу ближайшего охватывающего цикла.

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

val s = person.name ?: return

Тип этих выражений — тип Nothing.

Метки break и continue

Любое выражение в Kotlin можно пометить меткой. Метки имеют вид идентификатора, за которым следует знак @, например 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 с указанной меткой переходит к точке выполнения сразу после цикла, помеченного этой меткой. continue переходит к следующей итерации этого цикла.

В некоторых случаях можно использовать break и continue нелокально, не определяя метки явно. Такое нелокальное использование допустимо в лямбда-выражениях, переданных во внешние inline-функции.

Возврат к меткам

В Kotlin функции можно вкладывать друг в друга с помощью функциональных литералов, локальных функций и объектных выражений. Квалифицированный return позволяет выполнить возврат из внешней функции.

Наиболее важный вариант использования — возврат из лямбда-выражения. Чтобы выполнить возврат из лямбда-выражения, пометьте его меткой и укажите её для return:

//sampleStart
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach lit@{
        if (it == 3) return@lit // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with explicit label")
}
//sampleEnd

fun main() {
    foo()
}

Теперь возврат происходит только из лямбда-выражения. Часто удобнее использовать неявные метки, поскольку такая метка совпадает с именем функции, которой передаётся лямбда-выражение.

//sampleStart
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach {
        if (it == 3) return@forEach // local return to the caller of the lambda - the forEach loop
        print(it)
    }
    print(" done with implicit label")
}
//sampleEnd

fun main() {
    foo()
}

В качестве альтернативы можно заменить лямбда-выражение на анонимную функцию. Оператор return в анонимной функции возвращает управление из самой анонимной функции.

//sampleStart
fun foo() {
    listOf(1, 2, 3, 4, 5).forEach(fun(value: Int) {
        if (value == 3) return  // local return to the caller of the anonymous function - the forEach loop
        print(value)
    })
    print(" done with anonymous function")
}
//sampleEnd

fun main() {
    foo()
}

Обратите внимание, что использование локальных возвратов в трёх предыдущих примерах аналогично использованию continue в обычных циклах.

Прямого эквивалента для break нет, но его можно имитировать, добавив внешнюю лямбда-функцию run и выполнив из неё нелокальный возврат:

//sampleStart
fun foo() {
    run loop@{
        listOf(1, 2, 3, 4, 5).forEach {
            if (it == 3) return@loop // non-local return from the lambda passed to run
            print(it)
        }
    }
    print(" done with nested loop")
}
//sampleEnd

fun main() {
    foo()
}

Нелокальный возврат здесь возможен, поскольку вложенная лямбда-функция forEach() является inline-функцией.

При возврате значения синтаксический анализатор отдаёт предпочтение квалифицированному возврату:

return@a 1

Это означает «вернуть 1 по метке @a», а не «вернуть выражение с меткой (@a 1)».

В некоторых случаях можно выполнить возврат из лямбда-выражения без использования меток. Такие нелокальные возвраты находятся внутри лямбда-выражения, но завершают выполнение внешней inline-функции.

25 июня 2025 г.
Условия и циклыОбработка исключений и ошибок

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

Spec-Zone.ru

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