What continue does
The continue statement ends the current pass through a loop and jumps to the next one. Whatever is left in the loop body is skipped for this element, but the loop itself keeps going. This is different from break, which ends the whole loop.
It is most useful as a filter. Instead of wrapping the real work in an if, you test for the elements you don't want, skip them with continue, and let the rest of the body deal with the elements that remain.
An example: ages at the door
ages := []int{10, 30, 21, 19, 25}
for _, age := range ages {
if age < 21 {
continue
}
fmt.Printf("Someone of age %d entered the bar.\n", age)
}
The output is:
Someone of age 30 entered the bar.
Someone of age 21 entered the bar.
Someone of age 25 entered the bar.
Tracing the loop:
- For
10, the conditionage < 21is true,continueruns, and the print is skipped. - For
30, the condition is false, so the body continues to the print. - For
21, the condition is false, because 21 is not less than 21. The person gets in. - For
19, the condition is true and the print is skipped again. - For
25, the condition is false and the print runs.
Notice that no else is needed. After continue the rest of the body never runs, so the code below the if only sees the elements that passed the test.
Go details
- The condition has no parentheses. Go writes
if age < 21 {, and the braces are required even for one statement. - The blank identifier.
rangeyields an index and a value. A variable you declare but never use is a compile error, so the index you don't need is written as_. - In a three-part loop, the post statement still runs. With
for i := 0; i < 5; i++, acontinuejumps toi++and then to the condition check, so the loop doesn't get stuck. Printing only the odd numbers works like this:
for i := 0; i < 5; i++ {
if i%2 == 0 {
continue
}
fmt.Println(i)
}
1
3
- Only the innermost loop is affected. In nested loops, a plain
continuemoves to the next iteration of the inner loop. To move on in the outer loop, label it and writecontinue outer. With the label on an outer loop overiand an inner loop overj, acontinue outeratj == 1prints only the pairs wherejis 0: (0,0), (1,0) and (2,0). - A
while-style loop can hang. Go writes a condition-only loop asfor cond { ... }. If the statement that changes the condition comes after thecontinue, it never runs for skipped elements, and the loop may repeat forever. Update the counter before thecontinuein such loops.
The exercise: heights for the arena
The slice heights holds the heights of the people in line. Only those who are at least 170 get into the arena, and the program prints the heights that pass.
- Loop over the heights.
for _, height := range heightsvisits each one and discards the index. - Skip the short ones. At least 170 means the ones to reject are those with
height < 170, so theifuses<and runscontinue. A height of exactly 170 would not be skipped. - Print the rest. After the
if,fmt.Println(height)runs only for heights that were not skipped.
heights := []int{180, 139, 174, 190, 162}
for _, height := range heights {
if height < 170 {
continue
}
fmt.Println(height)
}
This prints:
180
174
190
The values 139 and 162 are skipped.
Common mistakes
- Using
<=instead of<. That would reject people of exactly 170, who should be admitted. - Putting the print before the check. Then every height is printed, and the
continuehas nothing left to skip. - Using
breakinstead ofcontinue. The loop would stop at 139, so 174 and 190 would never be printed.
Key takeaways
continueskips the rest of the current iteration;breakends the loop.- Test for what you want to skip, and keep the main work after the
if, with noelse. - In a three-part
for,continuestill runs the post statement. - A label lets
continuetarget an outer loop.