我正在学习《铁 rust 》中的异步/等待,我一直在关注Tokio tutorial.在教程中,有一件事困扰着我,但教程似乎没有解释.考虑一下this

tokio::spawn(async move {
    process(socket).await;
});

本教程就是这么做的,但我搞不懂为什么这里要用async move {}块.到目前为止,据我所知,异步块是不必要的,也就是说,下面的代码运行得很好,而且更简洁直接:

tokio::spawn(process(socket));

所以,我的问题是

  1. 在此代码中是否需要使用异步块?
  2. 如果是这样,又有什么不同呢?
  3. 如果没有编译器优化,异步块不会增加一层额外的间接层,可能会导致性能略有下降吗?

推荐答案

  1. 在此代码中是否需要使用异步块?

大多数情况下,答案是否定的;但请看下一个答案.

  1. 如果是这样,又有什么不同呢?

在 case process()被定义为async fn的情况下,什么都不是.有些人喜欢一种形式,但这是主观的.

但是,如果将process()定义为返回Future的常规函数,则存在差异:对于async块,在新派生的任务中执行allprocess(),而在没有它的情况下,对process()的调用在父任务中执行,并且只在派生任务中执行它返回的future .

这可能很重要,例如,如果process()返回的future 不是'static(或Send),在这种情况下,没有async块的呼叫将失败.或者如果process()本身可能很昂贵,我们希望它在另一个任务中执行,而不仅仅是它返回的future .

需要注意的是,在调用Runtime::block_on()时也有类似的区别,但这里的区别更重要:如果没有async块,process()中的代码将执行outside of the async runtime.这意味着对需要活动运行时(例如tokio::spawn())的函数的调用将失败.

  1. 如果没有编译器优化,异步块不会增加一层额外的间接层,可能会导致性能略有下降吗?

我不知道生成器(以及在生成器上实现的异步函数和块)的具体实现细节,但这不太可能.Rust中的异步块不分配,我不认为使用只转发的async块会产生任何开销.

Rust相关问答推荐

通用池类型xsx

什么是谓词的简短和简洁类型

为什么我不能从带有字符串的 struct 的引用迭代器中收集VEC<;&;str&>?

Box::new()会从一个堆栈复制到另一个堆吗?

除了调用`waker.wake()`之外,我如何才能确保future 将再次被轮询?

如何计算迭代器适配器链中过滤的元素的数量

铁 rust ,我的模块介绍突然遇到了一个问题

无符号整数的Rust带符号差

零拷贝按步骤引用一段字节

为什么Deref类特征不构成?

习语选项<;T>;到选项<;U>;当T->;U用From定义

如何迭代属性以判断相等性?

这是什么:`impl Trait for T {}`?

我应该如何表达具有生命周期参数的类型的总排序,同时允许与不同生命周期进行比较?

Rust Axum 框架 - 解包安全吗?

Rust:为什么 Pin 必须持有指针?

如何将这些测试放在一个单独的文件中?

Rust 中函数的类型同义词

在 Rust 中退出进程

有没有办法在 Rust 中对 BigInt 进行正确的位移?