Label in Kotlin starts with an identifier which is followed by @ . Here, test@ is a label marked at the outer while loop. Now, by using break with a label ( break@test in this case), you can break the specific loop.
How labeled continue works? Label in Kotlin starts with an identifier which is followed by @ . Here, outerloop@ is a label marked at outer while loop. Now, by using continue with the label ( continue@outerloop in this case), you can skip the execution of codes of the specific loop for that iteration.
break ends execution of the current for , foreach , while , do-while or switch structure.
Note : There is no way to stop or break a forEach loop. The solution is to use Array.
This will print 1 to 5. The return@forEach
acts like the keyword continue
in Java, which means in this case, it still executes every loop but skips to the next iteration if the value is greater than 5.
fun main(args: Array<String>) {
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
nums.forEach {
if (it > 5) return@forEach
println(it)
}
}
This will print 1 to 10 but skips 5.
fun main(args: Array<String>) {
val nums = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
nums.forEach {
if (it == 5) return@forEach
println(it)
}
}
Try them at Kotlin Playground.
Edit:
According to Kotlin's documentation, it is possible to simulate continue
using annotations.
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@ {
if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
If you want to simulate a break
, just add a run
block
fun foo() {
run lit@ {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
}
Original Answer:
Since you supply a (Int) -> Unit
, you can't break from it, since the compiler do not know that it is used in a loop.
You have few options:
Use a regular for loop:
for (index in 0 until times) {
// your code here
}
If the loop is the last code in the method
you can use return
to get out of the method (or return value
if it is not unit
method).
Use a method
Create a custom repeat method method that returns Boolean
for continuing.
public inline fun repeatUntil(times: Int, body: (Int) -> Boolean) {
for (index in 0 until times) {
if (!body(index)) break
}
}
A break can be achieved using:
//Will produce "12 done with nested loop"
//Using "run" and a tag will prevent the loop from running again.
//Using return@forEach if I>=3 may look simpler, but it will keep running the loop and checking if i>=3 for values >=3 which is a waste of time.
fun foo() {
run loop@{
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@loop // non-local return from the lambda passed to run
print(it)
}
}
print(" done with nested loop")
}
And a continue can be achieved with:
//Will produce: "1245 done with implicit label"
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return@forEach // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with implicit label")
}
As anyone here recommends... read the docs :P https://kotlinlang.org/docs/reference/returns.html#return-at-labels
EDIT: While the main question asks about forEach, it's important to consider the the good old "for". Using Kotlin doesn't mean we need to use forEach all the time. Using the good old "for" is perfectly ok, and sometimes even more expressive and concise than forEach:
fun foo() {
for(x in listOf(1, 2, 3, 4, 5){
if (x == 3) break //or continue
print(x)
}
print("done with the good old for")
}
You can use return from lambda expression which mimics a continue
or break
depending on your usage.
This is covered in the related question: How do I do a "break" or "continue" when in a functional loop within Kotlin?
As the Kotlin documentation says, using return
is the way to go. Good thing about kotlin is that if you have nested functions, you can use labels to explicity write where your return is from:
Function Scope Return
fun foo() {
listOf(1, 2, 3, 4, 5).forEach {
if (it == 3) return // non-local return directly to the caller of foo()
print(it)
}
println("this point is unreachable")
}
and Local Return (it doesn't stop going through forEach = continuation)
fun foo() {
listOf(1, 2, 3, 4, 5).forEach lit@{
if (it == 3) return@lit // local return to the caller of the lambda, i.e. the forEach loop
print(it)
}
print(" done with explicit label")
}
Check out the documentation, it's really good :)
continue
type behaviour in forEach
list.forEach { item -> // here forEach give you data item and you can use it
if () {
// your code
return@forEach // Same as continue
}
// your code
}
for break
type behaviour you have to use for in until
or for in
as per the list is Nullable
or Non-Nullable
For Nullable list:
for (index in 0 until list.size) {
val item = list[index] // you can use data item now
if () {
// your code
break
}
// your code
}
For Non-Nullable list:
for (item in list) { // data item will available right away
if () {
// your code
break
}
// your code
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With