#rust
#Ржавчина
Вопрос:
У меня есть общая асинхронная функция. Я хочу вызвать его с разными типами и запустить полученные фьючерсы параллельно. Но похоже, что он создает фьючерсы разных типов (хотя все они являются impl Future<Output=()> ) , поэтому я не могу помещать объекты разных типов в вектор, поэтому я не могу вызвать функцию выбора. Вот что я имею в виду:
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;
}
И это не работает:
use std::fmt::Debug;
#[tokio::main]
async fn main() {
// one argument to test() is i32, the second argument is amp;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;
}
В моем конкретном примере я могу использовать select, который принимает два фьючерса, но что, если у меня много фьючерсов? Как я могу выбрать несколько фьючерсов с разными типами?
Ответ №1:
вам просто нужно немного помочь компилятору определить правильный тип. Здесь мы используем динамическую диспетчеризацию с dyn
ключевым словом.
use std::fmt::Debug;
use std::pin::Pin;
#[tokio::main]
async fn main() {
// one argument to test() is i32, the second argument is amp;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;
}
Итак, все, что я сделал, это извлек вектор в переменную и присвоил ему явный тип.