A question about the continue statement

Hello,
Why is this code executed only once? When number is 2, then if command is true and continue statement is executed. What happens after that? As far as I know, continue vs. break.

fn main() {
    let mut number = 1;
    while number <= 10 {
        if (number % 2) == 0 {
        continue;
        }
        println!("{}", number);
        number += 1;
    }
}

Thank you.

The code executes the loop for number = 1, prints it in the println, increments it to 2, and then starts the next loop iteration.

With number = 2 now, the if statements is true (since 2 is even, and number % 2 == 0 checks for evenness), so the continue expression/statement is evaluated.

The effect of continue is “continue with the next loop iteration”. You can think of ever loop

while CONDITION {
    DO_SOME_STUFF;
    DO_SOME_STUFF;
}

as having an implicit continue statement at the end, too, like

while CONDITION {
    DO_SOME_STUFF;
    DO_SOME_STUFF;
    continue;
}

With the continue in the if, it’s analogous to an “early return” in a function as such a continue goes back to the next while iteration (unless the while condition is false now), without iterating the rest of the loop body to its end first.

For this reason, the effect of the continue being reached is that number is not further incremented, is stays 2, the while loop goes into it’s 3rd iteration now, 2 is still less than 10, we reach the if statement another time, continue again, and essentially are trapped in an infinite loop :slight_smile:

4 Likes

You enter an endless loop here, because if number is 2, it will never be incremented again. continue stops the current iteration of the loop and jumps back to the beginning of the loop (now with number equal to 2). break on the other hand stops the loop and jumps to after the loop statement.

1 Like

Hello,
Thank you so much for your reply.
So, number += 1; must be after the while command.

Yes, you could increment number before the if statement to achieve what you are after, I guess (though I like @steffahn's third solution below best):

fn main() {
    let mut number = 0;
    
    while number <= 10 {
        number += 1;
    
        if (number % 2) == 0 {
            continue;
        }
        
        println!("{}", number);
    }
}

Playground.

2 Likes

A way to avoid an infinite loop would be to increment number in the continue case, too

fn main() {
    let mut number = 1;
    while number <= 10 {
        if (number % 2) == 0 {
            number += 1;
            continue;
        }
        println!("{}", number);
        number += 1;
    }
}

you could also invert the condition as in

fn main() {
    let mut number = 1;
    while number <= 10 {
        if (number % 2) != 0 {
            println!("{}", number);
        }
        number += 1;
    }
}

to have a unified += 1 statement. This approach would not use continue explicitly, but skips over the print by guarding it in an if statement instead.

Finally, to iterate over numbers from 1 to 10, it’s easiest to just use a for loop, which also supports continue, but will never skip the step of moving to the next item.

fn main() {
    for number in 1..=10 {
        if (number % 2) == 0 {
            continue;
        }
        println!("{}", number);
    }
}
4 Likes

It depends on what you mean by "after" and "command". There are no "commands" in Rust; there are only statements and expressions. If you mean that the increment must be the first statement inside the body of the loop, then that would work, except that everything printed would be 1 higher than the current code (because the increment would happen before the print, not after).

3 Likes

Depending on what you're trying to accomplish, you can also change your last one to use step_by to avoid the conditional inside the loop at all:

fn main() {
    for number in (1..10).step_by(2) {
        println!("{}", number);
    }
}

(though this is a pretty contrived example and if your conditional is any more complicated it's not useful)

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.