What continue does
The continue statement ends the current iteration of a loop and jumps straight to the next one. Any code below it in the loop body is skipped for that element, but the loop itself keeps going. Compare break, which ends the whole loop.
The example below lets in only people aged 21 or more:
val ages = intArrayOf(10, 30, 21, 19, 25)
for (age in ages) {
if (age < 21) {
continue
}
println("Someone of age $age entered the bar.")
}
Someone of age 30 entered the bar.
Someone of age 21 entered the bar.
Someone of age 25 entered the bar.
The ages 10 and 19 print nothing. The iterations go like this:
age = 10: the testage < 21is true, socontinueruns and theprintlnis skipped.age = 30: the test is false, so the program reaches theprintln.age = 21: 21 is not less than 21, so the test is false and the line prints. The boundary value is let in.age = 19: skipped, like the first.age = 25: printed.
The string "... $age ..." is a string template: Kotlin replaces $age with the variable's value.
The exercise
The task is to let into the arena only the people whose height is at least 170. The starting code is the array:
val heights = intArrayOf(180, 139, 174, 190, 162)
The steps:
- Loop over the heights.
for (height in heights)gives each value in turn. Kotlin works out the type ofheightfrom the array, so you don't write one. - Skip the short ones. Inside the loop, if
heightis less than170, callcontinue. The test checks the rejection condition ("less than 170"), which is the opposite of the requirement ("at least 170"). - Print the rest. Below the
if, printheight. This line is reached only by heights that passed the check.
val heights = intArrayOf(180, 139, 174, 190, 162)
for (height in heights) {
if (height < 170) {
continue
}
println(height)
}
The output is:
180
174
190
139 and 162 are skipped. A height of exactly 170 would be printed, because 170 is not less than 170.
Continue or a positive if?
The same result is possible without continue, by testing the condition you want and putting the work inside the if:
for (height in heights) {
if (height >= 170) {
println(height)
}
}
Both versions print the same three numbers. With one statement to run, the second is shorter. continue pays off when the loop body is long: rejecting the unwanted elements at the top keeps the real work at one level of indentation instead of burying it inside a large if block.
Continue in nested loops
A plain continue applies to the innermost loop it is in. To move on to the next iteration of an outer loop, put a label on that loop:
val g = arrayOf(intArrayOf(1, 2, 3), intArrayOf(4, 5, 6))
outer@ for (row in g) {
for (v in row) {
if (v % 2 == 0) continue@outer
println(v)
}
}
For the first row, 1 prints, then 2 triggers continue@outer, which abandons that row. For the second row, 4 is even, so the row is abandoned before anything prints. The output is just 1.
Common mistakes
- Putting the work before the check. If
println(height)comes above theif, every height is printed, because the skip happens too late to matter. - Using the wrong comparison.
height <= 170would wrongly skip a person who is exactly 170. The requirement "at least 170" means only values below 170 are skipped. - Using break by mistake.
breakwould stop at 139 and print only180. Usecontinuewhen later elements still need to be processed. - Continue in a while loop. Be careful when the counter is updated at the bottom of the body:
continueskips that update too, and the loop can run forever. Aforloop advances on its own, which avoids this problem.
Key takeaways
continueskips the rest of the current iteration and moves to the next element.- It is written as a guard at the top of the loop body: test for what to skip, then do the work.
- With nested loops, plain
continueaffects the innermost loop;continue@labeltargets an outer one.