futures::select有什么区别! tokio::select?

What is the difference between futures::select! and tokio::select?

我正在使用 Tokio,我想接收来自两个不同 mpsc 队列的请求。 select! 似乎是要走的路,但我不确定 futures::select!tokio::select! 之间有什么区别。在什么情况下你应该使用一个而不是另一个?

tokio::select! 是根据 futures::select! 的经验构建的,但对其进行了一些改进以使其更符合人体工程学。例如。 select!futures-rs 版本需要 Futures 来实现 FusedFuture,而 Tokio 的版本不再需要这个。

取而代之的是,Tokio 的版本支持宏中的前提条件以涵盖相同的用例。

PR in the tokio repo 对此进行了详细说明。

此更改也是 proposed for the futures-rs version,但目前尚未实施。

如果您的项目中已经包含了 Tokio,那么使用 Tokio 的版本似乎更可取。但是,如果您没有也不想添加额外的依赖项,那么 futures-rs 版本也将以几乎相同的方式涵盖大多数用例。主要的区别是一些Future可能需要通过FutureExt::fuse()扩展方法转换成FusedFuture

为了补充@matthias247 的回答,一个相关的大区别是 futures::select! 在分支表达式 by mutable reference 中采用 futures,因此未完成的 futures 可以在循环中重新使用。

tokio::select!,另一方面,consumes passed futures. To get behavior similar to futures::select! you need to explicitly pass a reference (e.g. &mut future), and pin it if necessary (e.g. if it is async fn). Tokio docs have a section on this, Resuming an async operation

This thread 对 Tokio 决定不使用 FusedFuture 的原因有深入的解释。