主要观点:使用 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) `代码` - 列表 > 引用。你还可以使用@来通知其他用户。