Know which scope a jump exits
return exits a function, break exits a loop, and continue skips to its next iteration. Labels make the target explicit when nested loops or lambdas would otherwise be ambiguous.
fun visibleTopics(topics: List<String>): List<String> {
val result = mutableListOf<String>()
topics.forEach { topic ->
if (topic.isBlank()) return@forEach
result.add(topic.trim())
}
return result
}
return@forEach finishes only the current lambda invocation; later elements are still visited. An unlabelled return inside this inline forEach could return from visibleTopics itself. That distinction can create subtle bugs when replacing a loop with a higher-order function.
Prefer an ordinary loop when break and continue make the control flow easier to follow. Labels should clarify a real nesting problem, not compensate for excessive nesting.
Exercise
Given listOf("Kotlin", "", "Compose"), confirm both names survive. Then write a loop that stops at the first "STOP" token, ignoring blank entries before it.
Check: input Kotlin, blank, STOP, Compose returns only Kotlin. Explain why skipping an element and stopping iteration need different control-flow operations.