`|_| 和有啥区别?异步移动 ` 和 `异步移动 |_| `

Posted

技术标签:

【中文标题】`|_| 和有啥区别?异步移动 ` 和 `异步移动 |_| `【英文标题】: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)

【问题讨论】:

【参考方案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 ...

以上是关于`|_| 和有啥区别?异步移动 ` 和 `异步移动 |_| `的主要内容,如果未能解决你的问题,请参考以下文章

异步编程和多线程有啥区别?

java中同步和异步有啥异同?

阻塞与同步、非阻塞和异步有啥区别? [复制]

同步和异步编程有啥区别(在node.js中)

redux 工具包查询和创建异步 thunk 有啥区别?

unix套接字中的异步和非阻塞有啥区别?