是否可以将 async_trait 与动态调度一起使用
Is it possible to use async_trait with dynamic dispatch
我正在尝试创建一个 async_trait,它使用迭代器的动态引用。
这是我的代码示例:
#[async_trait::async_trait]
trait StringPrinter {
async fn print(a: &mut dyn Iterator<Item = String>);
}
struct MyStringPrinter{}
#[async_trait::async_trait]
impl StringPrinter for MyStringPrinter {
async fn print(a: &mut dyn Iterator<Item = String>){
a.for_each(|x| println!("{}", x));
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
但是编译器抱怨:future created by async block is not 'Send'
另一方面 - 异步函数的简单版本运行良好:
async fn print_iterator(a: &mut dyn Iterator<Item = String>) {
a.for_each(|x| println!("{}", x));
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
知道有什么不同吗?或任何解决方法的想法?
是的,这是可能的,毕竟 #[async_trait]
proc-macro 重写了使用盒装 future 的方法。这在 crate 的 documentation 中有解释:
Async fns get transformed into methods that return Pin<Box<dyn Future + Send + 'async>>
and delegate to a private async
freestanding function.
但是当且仅当其所有成员都实现 Send
时,生成的未来将是 Send
。然而你的迭代器没有:
&mut dyn Iterator<Item = String>
只需将其更改为:
&mut (dyn Iterator<Item = String> + Send)
我正在尝试创建一个 async_trait,它使用迭代器的动态引用。
这是我的代码示例:
#[async_trait::async_trait]
trait StringPrinter {
async fn print(a: &mut dyn Iterator<Item = String>);
}
struct MyStringPrinter{}
#[async_trait::async_trait]
impl StringPrinter for MyStringPrinter {
async fn print(a: &mut dyn Iterator<Item = String>){
a.for_each(|x| println!("{}", x));
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
}
但是编译器抱怨:future created by async block is not 'Send'
另一方面 - 异步函数的简单版本运行良好:
async fn print_iterator(a: &mut dyn Iterator<Item = String>) {
a.for_each(|x| println!("{}", x));
tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
}
知道有什么不同吗?或任何解决方法的想法?
是的,这是可能的,毕竟 #[async_trait]
proc-macro 重写了使用盒装 future 的方法。这在 crate 的 documentation 中有解释:
Async fns get transformed into methods that return
Pin<Box<dyn Future + Send + 'async>>
and delegate to a privateasync
freestanding function.
但是当且仅当其所有成员都实现 Send
时,生成的未来将是 Send
。然而你的迭代器没有:
&mut dyn Iterator<Item = String>
只需将其更改为:
&mut (dyn Iterator<Item = String> + Send)