Hello, I'm having an issue with boxed dyn traits and lifetimes...
Here is the code:
use async_trait::async_trait;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
struct Item {}
#[async_trait]
trait FetchItems: Send + Sync {
async fn fetch_items(&self) -> Vec<Item>;
}
struct ItemFetcher {
item_fetchers: Vec<Box<dyn FetchItems>>,
}
impl ItemFetcher {
async fn run(&self) -> Vec<Item> {
let items: Arc<Mutex<Vec<Item>>> = Arc::new(Mutex::new(Vec::new()));
let mut handles = vec![];
for item_fetcher in self.item_fetchers.iter() {
let items = items.clone();
handles.push(tokio::spawn(async move {
let mut fetched_items = item_fetcher.fetch_items().await;
items.lock().unwrap().append(&mut fetched_items);
}));
}
for handle in handles {
handle.await.unwrap();
}
let items = items.lock().unwrap().to_vec();
items
}
}
struct SomeItemFetcher {}
#[async_trait]
impl FetchItems for SomeItemFetcher {
async fn fetch_items(&self) -> Vec<Item> {
vec![]
}
}
#[tokio::main]
async fn main() {
let item_fetcher = ItemFetcher {
item_fetchers: vec![Box::new(SomeItemFetcher {})],
};
let items = item_fetcher.run().await;
}
And here is the error:
Compiling playground v0.0.1 (/playground)
error[E0521]: borrowed data escapes outside of associated function
--> src/main.rs:21:29
|
17 | async fn run(&self) -> Vec<Item> {
| -----
| |
| `self` is a reference that is only valid in the associated function body
| let's call the lifetime of this reference `'1`
...
21 | for item_fetcher in self.item_fetchers.iter() {
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `self` escapes the associated function body here
| argument requires that `'1` must outlive `'static`
For more information about this error, try `rustc --explain E0521`.
error: could not compile `playground` due to previous error
I've been searching for a while but I'm unable to find the solution, I've had other issues previously but they where fixed by adding the Send + Sync
to the trait. This is the last one to get my code to compile, I'm sure it's something dumb...
Anyways if anybody could help me figure this out it would be awesome!