What is an implicit label in Kotlin, and how do you give a lambda an explicit label to target with a qualified return?
answer
- Implicit label = function name
- Explicit label: name@ before the {
- Explicit label shadows implicit
- Needed for nested same-function lambdas
- Anonymous fun → bare return is local
basics
~20 sBy default Kotlin names a lambda's label after the function it's passed to, so you can write return@forEach. You can override that by writing your own label before the lambda, like loop@ { ... }, and then use return@loop.
solid answer
~40 sWhen a lambda is the argument to a function, Kotlin gives it an **implicit label** equal to that function's name. So inside `list.map { ... }` you can write `return@map value` to return a result from just that lambda. You can also attach an **explicit label** yourself with the `label@` syntax placed right before the lambda's opening brace: `list.forEach myLoop@ { ... return@myLoop }`. An explicit label is required when implicit naming is ambiguous — for instance nested calls to the same function — or when you want a clearer name. Explicit labels shadow the implicit one. The same labeling grammar also drives labeled `break`/`continue` on ordinary loops, but for lambdas only qualified `return@label` applies.
code
kotlin · 8 linesval matrix = listOf(listOf(1, 2), listOf(3, 4))
matrix.forEach row@ {
it.forEach cell@ {
if (it == 3) return@row // skip the rest of THIS row
print("$it ")
}
}
// prints: 1 2 (row containing 3 is abandoned at 3)go deeper
Knows return@forEach exists and labels skip a lambda iteration.
Explains implicit naming, explicit name@ syntax, and shadowing.
Handles nested-lambda ambiguity and contrasts with anonymous-function local returns.
Weighs label readability and anonymous functions vs lambdas when designing DSLs and iteration helpers for maintainability.
## Implicit labels Whenever you pass a lambda directly as an argument to a function, Kotlin automatically gives that lambda a **label with the same name as the function**. This is the *implicit label*. ```kotlin listOf(1, 2, 3).map { if (it == 2) return@map 0 // implicit @map it * 10 } // result: [10, 0, 30] ``` For a value-producing lambda like `map`, `return@map x` makes `x` the value this iteration contributes. ## Explicit labels You can override the implicit name by attaching your own label with the `name@` syntax immediately **before** the lambda's `{`: ```kotlin listOf(1, 2, 3).forEach outer@ { if (it == 2) return@outer // skip element 2 println(it) } ``` An explicit label **shadows** the implicit one — once you write `outer@`, `return@forEach` is no longer available there; you use `return@outer`. ## When you need an explicit label Nesting two lambdas from the *same* function makes the implicit label ambiguous: ```kotlin outer.forEach o@ { inner.forEach i@ { if (cond) return@o // jump out of the inner lambda back to outer } } ``` Without labels, `return@forEach` would only resolve to the **innermost** `forEach`. Explicit labels `o@`/`i@` let you choose which lambda to return from. ## Anonymous functions: a label-free alternative An anonymous function `fun(x: Int): Boolean { ... }` lets a bare `return` return from the anonymous function itself, with no label needed — a different way to get local-return semantics: ```kotlin listOf(1, 2, 3).forEach(fun(value) { if (value == 2) return // returns from the anonymous fun, not the outer one println(value) }) ``` ## Key terms - **Implicit label**: auto-name = the called function's name (`@map`, `@forEach`). - **Explicit label**: a user-given `name@` placed before the lambda brace. - **Shadowing**: an explicit label hides the implicit one for that lambda. - **Anonymous function**: `fun(...) { ... }` literal whose bare `return` is local.
- If you write `forEach myLabel@ { ... }`, can you still use `return@forEach` inside it?No. The explicit label `myLabel@` shadows the implicit one, so only `return@myLabel` is valid for that lambda.
- How does an anonymous function change return semantics compared to a lambda?Inside an anonymous function, a bare `return` returns from the anonymous function itself (local), so you don't need a label and you don't get non-local return behavior.
saying these in an interview costs you the question
- Believing you must always write the label explicitly
- Placing the label after the brace instead of before it
- Thinking implicit and explicit labels can both be used on the same lambda
- Not recognizing nested same-function lambdas need explicit labels
- Confusing label syntax `name@` with annotation syntax `@name`