В вашем коде есть две ошибки:
Во-первых, функция, возвращающая impl Trait
, в настоящее время не может быть рекурсивной, поскольку фактический возвращаемый тип будет зависеть от самого себя.
Таким образом, чтобы ваш пример работалвам нужно вернуть размерный тип.Очевидным кандидатом является объект черты, то есть Box<Future<...>>
:
fn visit(path: PathBuf) -> Box<Future<Item = (), Error = Error>> {
...
let task = visit(entry.path());
tokio::spawn(task.map_err(drop));
...
Box::new(task)
}
Есть еще ваша вторая ошибка:
dyn futures::future::Future<...>` cannot be sent between threads safely
|
17 | tokio::spawn(task.map_err(drop));
| ^^^^^^^^^^^^ `dyn futures::future::Future<...>` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `dyn futures::future::Future<...>`
= note: required because of the requirements on the impl of `std::marker::Send` for `std::ptr::Unique<dyn futures::future::Future<...>`
= note: required because it appears within the type `std::boxed::Box<dyn futures::future::Future<...>`
= note: required because it appears within the type `futures::future::map_err::MapErr<...>`
= note: required by `tokio::executor::spawn`
Это означает, что ваш объект черты не Send
, поэтому его нельзя запланировать на выполнение в другом потоке, используя tokio::spawn()
.К счастью, это легко исправить: просто добавьте + Send
к вашему объекту черты:
fn visit(path: PathBuf) -> Box<Future<Item = (), Error = Error> + Send> {
...
}
См. Полный код на Playground .