【问题标题】:What is the difference between `|_| async move {}` and `async move |_| {}``|_| 和有什么区别?异步移动 {}` 和 `异步移动 |_| {}`
【发布时间】:2020-03-28 02:27:00
【问题描述】:

让我们考虑以下示例:

ma​​in.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"

我问的是表达式|x| async move {} 而不是async move |x| {}。后者比较明显,但是会遇到编译错误:

error[E0658]: async closures are unstable

那我想知道async move || {}|| async move {}有什么区别。它们似乎都是使用 move 关键字的闭包。

$ rustc --version
rustc 1.39.0 (4560ea788 2019-11-04)

【问题讨论】:

    标签: rust


    【解决方案1】:

    一个是异步块(准确地说是一个以异步块为主体的闭包),另一个是异步闭包。每async/await RFC

    async || 闭包

    除了函数,异步也可以应用于闭包。与异步函数一样,异步闭包的返回类型为impl Future&lt;Output = T&gt;,而不是T

    另一方面:

    async

    您可以使用async 块直接将未来创建为表达式。这种形式几乎等同于立即调用的async 闭包:

     async { /* body */ }
    
     // is equivalent to
    
     (async || { /* body */ })()
    

    除了 returnbreakcontinue 等控制流结构不允许在正文中使用。

    这里的move关键字表示异步闭包和阻塞是为了捕获它们关闭的变量的所有权。

    显然,异步闭包仍然被认为是不稳定的。它有this tracking issue

    【讨论】:

    • 所以现在它的导入没有区别,不是吗?
    • @dronte7 不,除了不稳定的事实。
    • 它们都立即变成了带有 ot 的 Future 而无需获取一些环绕变量。除了不稳定之外,异步闭包与获取外部变量的异步块相同,不是吗?
    • @dronte7 他们都返回一个 Future when 被调用。至于捕获变量,它们也是一样的。这就是闭包所代表的,异步与否。
    • 我认为在这两种情况下捕获变量是完全不同的。 async move || ... 会将变量从封闭块移动到闭包中,而|| async move {...} 会将变量从闭包移动到异步块中。如果你想将它们从封闭块移动到异步块中,我认为你现在需要使用move || async move {...}
    猜你喜欢
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-17
    相关资源
    最近更新 更多