Different type of move closures?

Is there any difference when putting the move keyword before or after the vertical bars?


fn main() {

   let _ = async move || {};

   let _ = move || {};

   let _ = || move {};

   let _ = || async move {};
}
1 Like

The first shouldn’t compile.

error: expected one of `async`, `|`, or `||`, found `{`
 --> src/main.rs:4:10
  |
4 | |x| move {}
  | ---      ^ expected one of `async`, `|`, or `||`
  | |
  | while parsing the body of this closure
  |
1 Like

okay hope it works now?

It's important to understand that there are two different expressions here which you're sticking together:

  • a closure, which always has the closure parameter list |...|
  • an async block, which always has the keyword async

Both closures and async blocks take move as a modifier, changing how they handle captured variables, in roughly the same way: "move all the captures into my resulting closure/future". So, the important thing for understanding the syntax is to look for || with or without a modifier, and async with or without a modifier. For your particular examples:

async move || {}

This is a syntax error, and so is async || {}, because it doesn't mean anything in stable Rust. In the future it might mean an “async closure” which will have some additional flexibility, but that is not available now.

move || {}

This is the move modifier attached to a closure. The values of variables captured by the closure (defined outside and used inside) will be moved into the closure when it is constructed, instead of being borrowed.

|| move {}

This is a syntax error, because move does not mean anything when applied to a plain block.

|| async move {}

This is a closure containing an async block, and the async block has the move modifier. It is not a specific syntax on its own but the combination of two. Let me try to make the distinction clearer: It's exactly the same meaning as, for example:

|| {
    let f = async move {};
    f
}
6 Likes