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ă.returnsimplu într-unforEachîn loc dereturn@forEach: iese din toată funcția, nu doar din pasul curent.breakîntr-un lambda care nu este inline (de exempluThread { ... }): 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.