Hacker News new | ask | show | jobs
by catfishx 1237 days ago
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.
1 comments

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.