Reputation: 1771
I have a generic async function. I want to invoke it with different types and run resulted futures in parallel. But it seems like it creates futures of different types(although they all are impl Future<Output=()>), hence I can't put objects of different types in Vector, hence I can't invoke select function. Here is what I mean:
use std::fmt::Debug;
#[tokio::main]
async fn main() {
// both arguments to test function i32. Works.
let first = Box::pin(test(5));
let second = Box::pin(test(6));
futures::future::select_all(vec![first, second]).await;
}
async fn test<T: Debug>(x: T) {
async {
println!("{:?}", x);
}.await;
}
And this doesn't work:
use std::fmt::Debug;
#[tokio::main]
async fn main() {
// one argument to test() is i32, the second argument is &str. Doesn't work
let first = Box::pin(test(5));
let second = Box::pin(test("five"));
futures::future::select_all(vec![first, second]).await;
}
async fn test<T: Debug>(x: T) {
async {
println!("{:?}", x);
}.await;
}
In my concrete example I can use select which accepts two futures, but what if I have a lot of futures? How can I select multiple futures with different types?
Upvotes: 4
Views: 2709
Reputation: 336
you just need to help the compiler a bit do detect the right type. We use dynamic dispatching with the dyn
keyword here.
use std::fmt::Debug;
use std::pin::Pin;
#[tokio::main]
async fn main() {
// one argument to test() is i32, the second argument is &str.
let first = Box::pin(test(5));
let second = Box::pin(test("five"));
let v: Vec<Pin<Box<dyn futures::Future<Output = ()>>>> = vec![first, second];
futures::future::select_all(v).await;
}
async fn test<T: Debug>(x: T) {
async {
println!("{:?}", x);
}
.await;
}
So all I have done was to extract the Vector into a variable and give it an explicit type.
Upvotes: 2