In rust you can use these almost everywhere in place of an expression (if statements, while loops, in function arguments, etc). It can sometimes make code a bit unreadable to some people, but its still a cool feature imo.
Conveniently in Rust because a block is an expression it lets you "convert" a statement (or sequence thereof) into an expression.
To be used sparingly, but very useful when it applies e.g. in the precise capture clause pattern, or for non-trivial object initialisation (as Rust doesn't have many literals or literal-ish macros).
Here's one notable use that I doubt many are familiar with:
let iter = some_iterator_expression;
{iter}.nth(2)
For some reason, nth takes &mut self instead of self (note that T: Iterator => &mut T: Iterator<Item=T::Item> so there was no need for this in the API design to support having access to the iterator after exhaustion; it was a mistake). So if you tried to use it like iter.nth(2) with the non-mut binding, that would fail. But {iter} forces iter to be moved - unlike (iter) which would not. Then iter becomes a temporary and we're free to call a &mut self method on it.
In general: {expression} turns a place expression into a value expression, i.e. forcing the place to be moved from.
Interesting. I don't see any use for it (since adding `mut` to the `let iter` declaration sounds less annoying than dropping `iter` altogether) but I learned something nonetheless, thank you.
To be used sparingly, but very useful when it applies e.g. in the precise capture clause pattern, or for non-trivial object initialisation (as Rust doesn't have many literals or literal-ish macros).