Reputation: 2579
Let's consider the following examples:
main.rs
use futures::executor::block_on;
use futures::future::{FutureExt, TryFutureExt};
async fn fut1() -> Result<String, u32> {
Ok("ok".to_string())
}
fn main() {
println!("Hello, world!");
match block_on(fut1().and_then(|x| async move { Ok(format!("{} is \"ok\"", x)) })) {
Ok(s) => println!("{}", s),
Err(u) => println!("{}", u)
};
}
Cargo.toml
[dependencies]
futures = "^0.3"
I'm asking about the expression |x| async move {}
instead of async move |x| {}
. The latter is more obvious, but it runs into the compilation error:
error[E0658]: async closures are unstable
Then I wonder, what is the difference between async move || {}
and || async move {}
. They both seems to be closures for using the move
keyword.
$ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)
Upvotes: 68
Views: 61914
Reputation:
As to some previous comments here, there appear to be various "issues" pertaining to the correct syntax.
(move |x| async move {foo(x)})(x).await
should be exactly equivalent to
(move |x| {async move {foo(x)}})(x).await
since a guarded closure apparently cannot be declared async
outside the guard, and declaring it async
inside the guard simply opens up another block of code, omitting the braces. The second move
moves all affected variables -- already moved into the closure -- into the async "safe space" so it would seem that all possible protections of async move
are applied here.
Upvotes: 1
Reputation: 14002
One is the async block (a closure with async block as its body to be precise), while the other is async closure. Per async/await RFC:
async ||
closuresIn addition to functions, async can also be applied to closures. Like an async function, an async closure has a return type of
impl Future<Output = T>
, rather thanT
.
On the other hand:
async
blocksYou can create a future directly as an expression using an
async
block. This form is almost equivalent to an immediately-invokedasync
closure:async { /* body */ } // is equivalent to (async || { /* body */ })()
except that control-flow constructs like
return
,break
andcontinue
are not allowed within body.
The move
keyword here is to denote that the async closure and block are to capture ownership of the variables they close over.
And apparently, async closure is still deemed to be unstable. It has this tracking issue.
Upvotes: 60