top | item 46336430

(no title)

pflanze | 2 months ago

No, unless you ask for it via the `move` keyword in front of the closure.

This works fine: https://play.rust-lang.org/?version=stable&mode=debug&editio...

discuss

order

schneems|2 months ago

Thanks. I was a genuine question and you answered it well. For some reason I've internalized that closures can capture variables sometimes, but I guess I'm not sure the conditions in which that's true (or perhaps I've learned/mis-remembered the wrong lesson a long time ago.

pflanze|1 month ago

If the code in the closure moves a value, then the closure becomes an FnOnce and does move the value out of the context. That's what you probably have in mind.

So, Rust does support partially-moving closures, and does so automatically.

But the converse is also true: Rust does not move values just because. If the code inside the closure doesn't move the context, then it will only move context if you use the `move` keyword (in which case the lifetime of the closure is not restricted by borrows of the context; Rust doesn't automatically move things to satisfy the closure's required lifetime, that's a manual decision process consistent with how Rust behaves in other places).

There's still one difference to the macro case: the closure borrows all the values at once. So if it needs &mut access to some variable in the context, you can't take another &mut to the same variable outside the closure as long as it is alive (as determined per what the non-lexical lifetime borrow checker can do). Those cases need to be worked around by instead passing in the &mut as a closure argument. Code deposited by macros is not subject to bundling all captures together, hence the borrow checker has more allowance to reduce the borrowing time of each borrow.