Future 不是 Send,只有当来自 async Trait 时
Future is not Send, only when from async Trait
我有一个特质Serializer
:
trait Serializer {
fn serialize(&self, data: Rc<()>) -> Result<(), Error>;
}
还有一些 Foo
实现了它。值得注意的是,data
不是 Send
。
实际实现需要异步上下文来执行,所以我将异步运行时的创建与实际实现分开,如下所示:
struct Foo {}
impl Foo {
async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
unimplemented!();
}
}
impl Serializer for Foo {
fn serialize(&self, data: Rc<()>) -> Result<(), Error> {
let runtime = Builder::new_current_thread().enable_all().build().unwrap();
runtime.block_on(async move { self.async_serialize(data).await })
}
}
这按我预期的方式编译和工作。
如果我重构代码,以便通过特征完成异步运行时创建:
#[async_trait]
trait AsyncSerializer {
async fn async_serialize(&self, data: Rc<()>) -> Result<(), Error>;
}
#[async_trait]
impl AsyncSerializer for Foo {
async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
unimplemented!();
}
}
这不编译,现在抱怨 Rc<()>
不是 Send
:
error: future cannot be sent between threads safely
--> src/main.rs:19:73
|
19 | async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
| _________________________________________________________________________^
20 | | unimplemented!();
21 | | }
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = Result<(), anyhow::Error>>`, the trait `Send` is not implemented for `Rc<()>`
note: captured value is not `Send`
这条错误消息对我来说很有意义,Rc
不是 Send
,而是:
- 为什么以前这不是问题?之前的实现(
impl on Foo
对比 impl AsyncSerializer for Foo
)与我相似。
- 我可以用某种方式包装
data
来避免这种情况吗?
#[async_trait]
de-sugars 您的代码要求发送期货的方式,如 here 所述。要解决此问题,请将属性宏更改为 #[async_trait(?Send)]
.
我有一个特质Serializer
:
trait Serializer {
fn serialize(&self, data: Rc<()>) -> Result<(), Error>;
}
还有一些 Foo
实现了它。值得注意的是,data
不是 Send
。
实际实现需要异步上下文来执行,所以我将异步运行时的创建与实际实现分开,如下所示:
struct Foo {}
impl Foo {
async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
unimplemented!();
}
}
impl Serializer for Foo {
fn serialize(&self, data: Rc<()>) -> Result<(), Error> {
let runtime = Builder::new_current_thread().enable_all().build().unwrap();
runtime.block_on(async move { self.async_serialize(data).await })
}
}
这按我预期的方式编译和工作。
如果我重构代码,以便通过特征完成异步运行时创建:
#[async_trait]
trait AsyncSerializer {
async fn async_serialize(&self, data: Rc<()>) -> Result<(), Error>;
}
#[async_trait]
impl AsyncSerializer for Foo {
async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
unimplemented!();
}
}
这不编译,现在抱怨 Rc<()>
不是 Send
:
error: future cannot be sent between threads safely
--> src/main.rs:19:73
|
19 | async fn async_serialize(&self, _data: Rc<()>) -> Result<(), Error> {
| _________________________________________________________________________^
20 | | unimplemented!();
21 | | }
| |_____^ future created by async block is not `Send`
|
= help: within `impl Future<Output = Result<(), anyhow::Error>>`, the trait `Send` is not implemented for `Rc<()>`
note: captured value is not `Send`
这条错误消息对我来说很有意义,Rc
不是 Send
,而是:
- 为什么以前这不是问题?之前的实现(
impl on Foo
对比impl AsyncSerializer for Foo
)与我相似。 - 我可以用某种方式包装
data
来避免这种情况吗?
#[async_trait]
de-sugars 您的代码要求发送期货的方式,如 here 所述。要解决此问题,请将属性宏更改为 #[async_trait(?Send)]
.