主要观点:使用 async Rust 和 Tokio 可能会遇到“future is not Send”编译器错误,在将一些顺序异步代码转换为使用流时,朋友提出了一种确定非 Send 错误来源的小技巧,此技巧可节省调试时间。
关键信息:
Future
必须是Send
,否则不能在 Tokio 中被spawn
,因为Future
结构代表异步操作的状态机,跨await
点使用非Send
值会使整个Future
非Send
。- 编译器首先会将注意力引导到边界检查失败的地方,即尝试
spawn
非Send
`Future的地方,而非
Future失去
Send`边界的地方。 - 可以通过用返回
Future
的普通fn
替代async fn
,或使用辅助函数send_static_future
来确保值实现Send
,以确定非Send
错误的来源。 - 在处理
Stream
时也会出现同样的问题,可使用类似方法确定非Send
的部分。
重要细节: - 给出了多个代码示例,如包含
async fn
和impl Future
返回类型的代码、使用send_static_future
辅助函数的代码、处理Stream
的代码等,并指出编译器错误指向的位置。 - 介绍了在实际项目[Scour]中遇到的问题及使用流和组合器的解决方案,以及一些相关的 Rust 库和工具,如
async-fn-stream
、pumps
、argus
等。 - 讨论链接:r/rust、Lobsters、Hacker News。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。