In a nested for loop, which loop does a plain `break` (without a label) terminate, and how do you instead break out of the outer loop?
answer
- Plain break = innermost loop only
- Label syntax: name@ before the loop
- break@label / continue@label target outer loop
- continue obeys the same innermost-vs-labeled rule
- Labels replace boolean-flag workarounds
basics
~10 sA plain break only stops the loop directly around it (the innermost one). To stop an outer loop, you put a name (label) on that loop and write break@name.
solid answer
~40 sA plain `break` terminates only the innermost enclosing loop; control resumes right after that loop. To target an outer loop you label it with an identifier followed by `@` (e.g. `outer@ for (...)`) and then use `break@outer`, which exits the loop carrying that label. The same rule applies to `continue`: plain `continue` skips to the next iteration of the innermost loop, while `continue@outer` jumps to the next iteration of the labeled outer loop. Labels in Kotlin are written `name@` before the loop, and referenced as `break@name` / `continue@name`. This avoids the boolean-flag workaround common in Java pre-labels and keeps nested-loop exit explicit and readable.
code
kotlin · 6 linesouter@ for (i in 1..3) {
for (j in 1..3) {
if (i * j > 4) break@outer
println("$i x $j = ${i * j}")
}
}go deeper
Knows plain break stops only the innermost loop and that a label lets you break an outer one.
Writes correct name@ placement and explains continue follows the same rule.
Articulates why labels beat boolean flags and notes break/continue are loop-only, distinct from return@.
Frames labeled jumps as a readability/intent tool and weighs them against extracting the loop into a function with early return.
## What `break` does by default Kotlin has three structural jump expressions: `break`, `continue`, and `return`. A **plain `break`** (no label) terminates the **nearest enclosing loop** — the loop whose body directly contains it. Execution continues at the first statement after that loop. In nested loops this matters: an inner `break` does NOT escape the outer loop. The outer loop simply continues with its next iteration. ```kotlin for (i in 1..3) { for (j in 1..3) { if (j == 2) break // breaks the INNER loop only println("$i,$j") } } // prints 1,1 2,1 3,1 -> outer loop still runs all 3 times ``` ## Labels: targeting an outer loop A **label** in Kotlin is an identifier followed by `@`, placed immediately before the loop you want to name: ```kotlin outer@ for (i in 1..3) { for (j in 1..3) { if (j == 2) break@outer // exits the OUTER loop entirely println("$i,$j") } } // prints only 1,1 -> the whole nested structure is abandoned ``` - `outer@` declares the label. The name is arbitrary; `loop@`, `rows@`, etc. are all valid. - `break@outer` says "break the loop carrying the label `outer`". ## `continue` follows the same rule - Plain `continue` -> next iteration of the **innermost** loop. - `continue@outer` -> next iteration of the **labeled** loop. ```kotlin outer@ for (i in 1..3) { for (j in 1..3) { if (j == 2) continue@outer // skip rest of inner loop AND advance i println("$i,$j") } } // prints 1,1 2,1 3,1 ``` ## Why this exists Without labels you'd need a boolean flag checked after the inner loop to break the outer one. Labeled jumps make the intent explicit. Note: `break`/`continue` are only valid inside loops (`for`, `while`, `do-while`); they are NOT used to exit a lambda — that uses labeled `return@` (a separate mechanism for the `Returns at Labels` topic).
- What happens if you write `break` with no label and no enclosing loop?It is a compile error — `break` and `continue` are only allowed inside a loop body.
- Can you put a label on a `while` loop too?Yes. Labels work on `for`, `while`, and `do-while` identically — `loop@ while (...) { ... break@loop }`.
A plain break is leaving the room you're standing in; break@building is walking out of the whole building you labeled.
saying these in an interview costs you the question
- Claiming plain `break` exits all enclosing loops
- Writing the label after the loop instead of before it
- Confusing `break@label` (loops) with `return@label` (lambdas)
- Thinking labels are required even for single loops