是否可以将 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)