Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

do-while loops in Rust

View blackmagic.rs
1 2 3 4 5 6 7
while {
let x = foo();
bar(x);
 
x != 0
} {}
 

what is the extra {} for?

@Stibbons while loops in Rust typically look like this:

while x != 0 {
    x = foo();
}

...but note that the condition there is allowed to be any expression. And blocks are themselves expressions. So you can write the above like this:

while { x != 0 } {
    x = foo();
}

What's been done here is that they've simply moved all the normal loop logic into the condition:

while { x = foo(); x != 0 } {
    // empty loop body
}

...such that it acts just like the typical do/while loop from other languages, thereby evaluating the loop body once before testing the condition. From there it's just a simple matter to reformat for style points:

while {
    x = foo();
    x != 0
} {}

Wonder if you could macro away the extra {}

No need to macro it away...

while {
    x = foo();
    x != 0
}                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            {}

There you go. :)

Arg, It's even worse : with this syntax, you don't see the dirty trick at all.
Until you try to use break or continue ...

i see :)

You can do the same trick in C, too:

int x;
while (
  x = foo(),
  bar(x),
  x != 0
) {}

and even weirder, like this (on some compilers):

int x;
while (({
  x = foo();
  bar(x);
  x != 0;
})) {}

This is an ancient thread but I thought I'd share a trick from my first rust project -- it's crazy that this still doesn't exist in stable rust (and I haven't found any mention of it in the nightly book).

macro_rules! run {
    ($x:block until $y:expr) => {{
        while {
            $x;
            !$y
            } {}
    }};
    ($x:block if_still $y:expr) => {{
        while {
            $x;
            $y
            } {}
    }};
}

Additionally, I think keyword! should be parsed seperately to keyword, so you could write this as do! while! without the compiler complaining.

(Should note that I never ended up using this macro because it was too ugly in use, so take from that what you will)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.