continue
The continue keyword skips all remaining statements in the current iteration of a loop, while, or for loop and jumps immediately to the start of the next iteration.
Behavior of continue Across Loop Types
While break terminates a loop completely, continue terminates only the current pass through the loop body. Where execution jumps next depends on the kind of loop:
| Loop Kind | What continue Does |
|---|---|
for item in iter |
Drops local variables in the current iteration, calls iter.next() to fetch the next item, and starts the next iteration (or exits if None) |
while condition |
Drops local variables in the current iteration and jumps directly to re-evaluating condition |
loop |
Drops local variables in the current iteration and jumps directly back to the opening { of the loop body |
continue 'label; |
Skips the rest of the current iteration of the outer loop named 'label and advances that labeled loop to its next iteration |
for n in [1, 2, 3] {
if n == 2 {
continue; -------+
} | (Skips `println!` when `n == 2`)
println!("{n}"); |
} <----------------------+ (Advances iterator to `n = 3`)
fn main() {
for number in 1..=6 {
if number % 2 == 0 {
continue; // Skip even numbers
}
println!("Odd number: {number}");
}
}
Odd number: 1
Odd number: 3
Odd number: 5
Flattening Loop Bodies with continue Guard Clauses
Just as return flattens deeply nested if blocks at the top of a function, continue acts as a per-iteration guard clause at the top of a loop body—filtering out invalid, commented, or empty items early so the main loop body stays unindented:
fn main() {
let config_lines = [
"# Server configuration",
"",
"host = 127.0.0.1",
" ",
"# Port setting",
"port = 8080",
];
for raw_line in config_lines {
let line = raw_line.trim();
// Guard 1: skip empty or whitespace-only lines
if line.is_empty() {
continue;
}
// Guard 2: skip comment lines starting with `#`
if line.starts_with('#') {
continue;
}
// Main loop work remains flat at a single level of indentation:
println!("Active setting: {line}");
}
}
Active setting: host = 127.0.0.1
Active setting: port = 8080
Innermost Loop Rule in Nested Loops
In nested loops, an unlabeled continue; affects only the innermost enclosing loop. To skip to the next iteration of an outer loop from inside an inner loop, attach a loop label ('outer: for ...) and write continue 'outer;:
fn main() {
'rows: for row_idx in 0..3 {
for col_idx in 0..3 {
if row_idx == 1 && col_idx == 1 {
println!(" Skipping rest of row {row_idx} via `continue 'rows`");
continue 'rows; // Jumps directly to `row_idx = 2`!
}
println!(" Visiting ({row_idx}, {col_idx})");
}
}
}
Visiting (0, 0)
Visiting (0, 1)
Visiting (0, 2)
Visiting (1, 0)
Skipping rest of row 1 via `continue 'rows`
Visiting (2, 0)
Visiting (2, 1)
Visiting (2, 2)
Pitfall: Updating the Counter Before continue in while and loop
In a for loop, the iterator advances automatically on continue. However, in a while or loop construct where you increment a counter manually, placing continue before the counter increment skips the increment and causes an infinite loop!
Infinite Loop Bug in `while`: Correct Placement in `while`:
let mut i = 0; let mut i = 0;
while i < 5 { while i < 5 {
if i == 2 { i += 1; <-- Incremented first!
continue; // `i` stays 2 forever! if i == 2 {
} continue;
i += 1; }
} }
fn main() {
let mut step = 0;
while step < 4 {
step += 1; // Updated BEFORE any `continue`
if step == 2 {
continue;
}
println!("Completed step {step}");
}
}
Completed step 1
Completed step 3
Completed step 4
continue as a Diverging Expression (!)
Like break and return, continue is an expression of the never type (!), because control never continues into the surrounding expression on that iteration. This makes continue particularly clean inside match arms or let ... else statements inside a loop:
fn main() {
let inputs = ["10", "invalid", "25", "", "40"];
let mut total = 0;
for raw in inputs {
// If parsing fails, `continue` skips this iteration; otherwise `n` is bound as `i32`!
let Ok(n) = raw.parse::<i32>() else {
println!("Skipping non-integer input: {raw:?}");
continue;
};
total += n;
}
println!("Total of valid integers: {total}");
}
Skipping non-integer input: "invalid"
Skipping non-integer input: ""
Total of valid integers: 75
Common Errors
Using continue Outside of a Loop (E0268)
continue can only appear inside a loop, while, or for loop (and unlike break, continue cannot target a plain labeled block 'block: { ... }):
// ❌ does not compile
fn main() {
'block: {
continue 'block;
}
}
error[E0696]: `continue` pointing to a labeled block
--> src/main.rs:3:9
|
2 | 'block: {
| ------- labeled block cannot be `continue`'d
3 | continue 'block;
| ^^^^^^^^^^^^^^^ labeled blocks cannot be `continue`'d
error: aborting due to 1 previous error