What is the difference between while and loop?

i could do the same as loop in while in rust i don't find the difference can you help me ?

loop is by default an infinite loop, so its type is ! (it's recognized as divergent by the compiler). This means that you can do something like this:

fn foo() -> i32 {
    loop {
        return 42;
    }
}

whereas this wouldn't compile:

fn foo() -> i32 {
    while true {
        return 42;
    }
}
6 Likes

very nice thank you so much

i have one more question please :

as i understand while and loop are the same but the idea behind that is :
loop : when i want to repeat the thing many times without any condition
while : when i want to repeat the thing till a condition met
i hope i am not wrong thank you in advance

A loop is also useful when the condition does not fit into the while structure; for example if you want to start by computing something, putting it into variables, then deciding whether to break the loop, then using the variables if you didn't. In a while you cannot do stuff that produces variables before the condition. (while let can, but that is not necessarily cleaner than loop.)

1 Like

In many cases you are likely to have a condition inside the loop to terminate it. If that condition happens to be at the top of the loop body then it is roughly equivalent to a while loop. You can choose either.

The nice thing about a loop is that it doesn't need a possibly meaningless condition at the top, like while true. Also it can return a value, unlike while:

let i = loop {
    break 42;
};

The nice thing about a while loop is that it reads well in many cases because it adds preconditions to the code in the loop and after the loop, as shown here by the asserts:

let i = 0u32;
while i < 10 {
   assert!(i < 10);
   // write i into a 1-character array;
   // choose another i;
}
assert!(i >= 10);
// chop off any fingers more than i

You can also include for here. It could be done using loop or while, but it makes dealing with Rust iterators nicer.

2 Likes

i actually had no problem using both of loop and while i used them many times that is why i could not find any difference

Many other programming languages don’t have a separate “loop” control flow structure, but you would use while true in them. In Rust, the right approach is really simply (idiomatically) that whenever you would write “while true”, you should write loop instead. If nothing else, it helps slightly with readability (especially for experienced Rust programmers who would expect you to use loop in such cases).

The additional benefits of loop that others have listed above (i.e. how it can return a value, or be of type ! when it never returns) are a nice-to-have addition, especially since Rust loves the “everything is an expression” approach and expressions have the ability to evaluate to a value, so it’s a good fit; and while perhaps not all-the-time, loop with return-values can be useful occasionally. Technically, it’s probably possible to re-write even a loop with return values into a while true loop that passes this “return value” out of the loop via some local variable, but that would be more tedious.


As for the benefit of while over loop…: well, at first it might seem more expressive, so maybe it’s not a fair comparison? But no, it’s really not! You can re-write your while loops into loops, translating

while condition(foo) {
    do_something(bar);
    do_something_else(baz);
}

as

loop {
    if condition(foo) {
        do_something(bar);
        do_something_else(baz);
    } else {
        break;
    }
}

or as

loop {
    if !condition(foo) { break }
    do_something(bar);
    do_something_else(baz);
}

and in fact, you should probably rewrite every (or … well … maybe at least most(?)) loops of the form

loop {
    if …condition… { break }
    … main body…
    … main body…
}

into the

while ...negated condition {
    … main body…
    … main body…
}

form. And coming back to the comparison again, the main advantage of while is readability. Readability is improved particularly well if the break; that’s avoided by using while instead of loop is the only break in the whole loop. @jongiddy added some relevant thought on that, regarding pre-conditions and post-conditions you get from while loops (without additional break;s).

(Someone also mentioned while let, and there’s a translation into loops for it as well, involving match instead of if, see here.)


So ultimately while and loop are similar, but they both exist, because it’s more convenient to have both in the language than having to work around the lack of the features of either by “emulating”/re-expressing it via the other.

5 Likes

The big difference is that rust knows that loop always runs at least once. It doesn't know that about while true in various analyses -- just like how it doesn't treat if true as always-running.

As the simplest demonstration of this, this compiles https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=380080b6eebce8769d33c0555b3399ed

    let x;
    loop {
        x = 4;
        break;
    }
    dbg!(x);

But this doesn't:

    let x;
    while true {
        x = 4;
        break;
    }
    dbg!(x);

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=3c28b7c7955ce231a3ebf38e1fc5eb5d

warning: denote infinite loops with `loop { ... }`
 --> src/main.rs:3:5
  |
3 |     while true {
  |     ^^^^^^^^^^ help: use `loop`
  |
  = note: `#[warn(while_true)]` on by default

error[E0381]: used binding `x` is possibly-uninitialized
 --> src/main.rs:7:10
  |
2 |     let x;
  |         - binding declared here but left uninitialized
3 |     while true {
  |           ---- if this condition isn't met and the `while` loop runs 0 times, `x` is not initialized
...
7 |     dbg!(x);
  |          ^ `x` used here but it is possibly-uninitialized
5 Likes

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.