break și continue în Kotlin

Controlul execuției Kotlin 1.0 (în lambda inline: Kotlin 2.2)

break oprește bucla curentă; continue sare la pasul următor. Cu etichete (nume@) pot opri o buclă exterioară.

Sintaxă
break            // ieși din bucla curentă
continue         // treci la pasul următor

exterior@ for (...) {
    for (...) {
        break@exterior
    }
}

Ce face break și continue

break oprește imediat bucla for, while sau do-while în care se află; programul continuă cu instrucțiunea de după buclă. continue abandonează doar pasul curent și trece la următorul. Sunt utile când cauți ceva (te oprești la primul găsit) sau când vrei să sari peste elemente nepotrivite.

În bucle imbricate, break și continue afectează doar bucla cea mai apropiată. Ca să oprești o buclă exterioară, îi pui o etichetă (un nume urmat de @, de exemplu exterior@) și scrii break@exterior sau continue@exterior.

În lambda-ul lui forEach nu există o buclă propriu-zisă. Acolo, pentru „sari peste” folosești return@forEach. Din Kotlin 2.2, break și continue scrise într-un lambda inline (de exemplu let) dintr-o buclă for acționează asupra acelei bucle.

Exemple

Exemplul 1: Primul element găsit și elemente sărite

continue sare peste produsele epuizate. break oprește căutarea la primul produs scump.

fun main() {
    val produse = listOf("pâine" to 5, "cafea" to 0, "brânză" to 38, "vin" to 65, "apă" to 3)
    for ((nume, pret) in produse) {
        if (pret == 0) {
            println("$nume: epuizat, sar peste")
            continue
        }
        if (pret > 50) {
            println("$nume costă $pret lei, mă opresc aici")
            break
        }
        println("$nume: $pret lei")
    }
    println("Gata cumpărăturile")
}

Rezultat

pâine: 5 lei
cafea: epuizat, sar peste
brânză: 38 lei
vin costă 65 lei, mă opresc aici
Gata cumpărăturile

Exemplul 2: Etichete pentru bucle imbricate

break@cautare oprește ambele bucle când găsește primul loc liber.

fun main() {
    val sala = listOf(
        listOf(true, true, true),
        listOf(true, false, true),
        listOf(false, false, false),
    )
    cautare@ for ((rand, locuri) in sala.withIndex()) {
        for ((loc, ocupat) in locuri.withIndex()) {
            if (!ocupat) {
                println("Primul loc liber: rândul ${rand + 1}, locul ${loc + 1}")
                break@cautare
            }
        }
        println("Rândul ${rand + 1} este plin")
    }
}

Rezultat

Rândul 1 este plin
Primul loc liber: rândul 2, locul 2

Exemplul 3: „continue” în forEach și break în lambda inline

return@forEach încheie doar pasul curent. În bucla for, continue și break din let (Kotlin 2.2) acționează asupra buclei.

fun main() {
    val note = listOf("9", "abc", "7", "", "10")
    note.forEach { text ->
        if (text.isBlank()) return@forEach
        println("forEach: $text")
    }

    for (text in note) {
        val n = text.toIntOrNull() ?: continue
        n.let {
            if (it == 10) break
            println("for: nota $it")
        }
    }
}

Rezultat

forEach: 9
forEach: abc
forEach: 7
forEach: 10
for: nota 9
for: nota 7

Greșeli frecvente

  • break în bucla interioară când vrei să oprești totul: iese doar din bucla interioară. Folosește o etichetă.
  • return simplu într-un forEach în loc de return@forEach: iese din toată funcția, nu doar din pasul curent.
  • break într-un lambda care nu este inline (de exemplu Thread { ... }): nu compilează, pentru că lambda-ul poate rula în alt moment.

Comenzi înrudite

  • for: Parcurge pe rând elementele unei colecții, ale unui interval sau ale oricărui obiect care are iterator().
  • while și do-while: while repetă un bloc cât timp condiția e adevărată; do-while execută blocul o dată, apoi verifică condiția.
  • return: Încheie funcția curentă și întoarce o valoare apelantului; cu etichetă (return@forEach) iese doar din lambda.
  • lambda: O lambda este o funcție fără nume, scrisă între acolade, pe care o poți pune într-o variabilă sau trimite altei funcții.