我想生成一个Vec,然后用join_all执行它们
到目前为止,我已经尝试过此代码
#![feature(async_await)]
use futures::future::join_all;
use std::future::Future;
async fn hello(name: &str) -> String {
format!("Hello {}!", name)
}
async fn main() {
let urls = vec!["Peter", "Hans", "Jake"];
let mut requests : Vec<Box<dyn Fn() -> Box<dyn Future<Output=String>>>> = vec![];
for url in urls {
requests.push(Box::new(|| Box::new(hello(&url))));
}
let responses : Vec<String> = join_all(requests).await;
println!("Response: {:?}", responses);
}
但是我收到以下错误消息。
error[E0277]: the trait bound `dyn std::ops::Fn() -> std::boxed::Box<dyn core::future::future::Future<Output = std::string::String>>: std::marker::Unpin` is not satisfied
--> src/main.rs:15:45
|
15 | let responses : Vec<String> = join_all(requests).await;
| ^^^^^^^^ the trait `std::marker::Unpin` is not implemented for `dyn std::ops::Fn() -> std::boxed::Box<dyn core::future::future::Future<Output = std::string::String>>`
|
::: /home/peter/.cargo/registry/src/github.com-1ecc6299db9ec823/futures-util-preview-0.3.0-alpha.19/src/future/join_all.rs:118:14
|
118 | I::Item: Future,
| ------ required by this bound in `futures_util::future::join_all::join_all`
|
= note: required because of the requirements on the impl of `core::future::future::Future` for `std::boxed::Box<dyn std::ops::Fn() -> std::boxed::Box<dyn core::future::future::Future<Output = std::string::String>>>`
答案 0 :(得分:1)
join_all
需要期货的迭代器,而不是返回期货的函数的迭代器:
pub fn join_all<I>(i: I) -> JoinAll<<I as IntoIterator>::Item>
where
I: IntoIterator,
<I as IntoIterator>::Item: Future,
此外,您的期货无法固定,因此join_all
无法使用它们。
最短的解决方法是:
use futures::future; // 0.3.5
use std::{future::Future, pin::Pin};
async fn hello(name: &str) -> String {
format!("Hello {}!", name)
}
pub async fn example() {
let urls = vec!["Peter", "Hans", "Jake"];
let mut requests: Vec<Box<dyn Fn() -> Pin<Box<dyn Future<Output = String>>>>> = vec![];
for url in urls {
requests.push(Box::new(move || Box::pin(hello(&url))));
}
let responses: Vec<String> = future::join_all(requests.into_iter().map(|r| r())).await;
println!("Response: {:?}", responses);
}
这可以更简洁地写为:
use futures::future::{self, FutureExt, LocalBoxFuture}; // 0.3.5
async fn hello(name: &str) -> String {
format!("Hello {}!", name)
}
pub async fn example() {
let urls = vec!["Peter", "Hans", "Jake"];
let mut requests: Vec<Box<dyn Fn() -> LocalBoxFuture<'static, String>>> = vec![];
for url in urls {
requests.push(Box::new(move || hello(&url).boxed_local()));
}
let responses: Vec<String> = future::join_all(requests.into_iter().map(|r| r())).await;
println!("Response: {:?}", responses);
}
但是,对于您的特定示例,这些都不需要:
Vec
use futures::future; // 0.3.5
async fn hello(name: &str) -> String {
format!("Hello {}!", name)
}
pub async fn example() {
let urls = vec!["Peter", "Hans", "Jake"];
let hellos = urls.iter().map(|u| hello(u));
let responses = future::join_all(hellos).await;
println!("Response: {:?}", responses);
}
另请参阅: