Вы не можете использовать impl Trait
таким образом. Чтобы иметь возможность хранить различные типы, которые реализуют признак, в одном и том же контейнере, вы должны использовать динамическую диспетчеризацию, сохраняя что-то вроде Box<dyn Trait>
.
. В вашем конкретном случае вы не указываете, хотите ли вы сохранитьСами асинхронные функции или будущее, сгенерированное асинхронными функциями, решение будет несколько другим.
Чтобы хранить только фьючерсы, вы пишете контейнер, такой как:
let mut v: Vec<Box<dyn Future<Output=()>>> = vec![];
И затем простовызовите функцию, поместите ее в коробку и сохраните в контейнере:
v.push(Box::new(haha()));
Если вместо этого вы хотите сохранить саму асинхронную функцию, не вызывая ее, вам нужен контейнер с двойным dyn
:
let mut v2: Vec<Box<dyn Fn() -> Box<dyn Future<Output=()>>>> = vec![];
Теперь, поскольку ваша функция haha
не реализует эту черту Fn
, вам нужен адаптер. Лямбда-функция будет работать просто замечательно, и не забудьте двойное Box
:
v2.push(Box::new(|| Box::new(haha())));
ОБНОВЛЕНИЕ:
К сожалению, с этими решениями вы будетев состоянии создать вектор, но не .await
для вашего будущего. Для этого вам понадобится фьючерс на реализацию маркера Unpin
. Это гарантирует компилятору, что будущее не будет перемещено во время его работы, потому что это будет совершенно небезопасно. Вы можете добавить требование + Unpin
к фьючерсу, но async fn
не равно Unpin
, поэтому вы не можете заполнить вектор. Самый простой способ исправить это - использовать эту удобную функцию из std
:
pub fn into_pin(boxed: Box<T>) -> Pin<Box<T>>
for f in v2 {
f().into_pin().await;
}
К сожалению, она все еще нестабильна. К счастью, есть From
impl, который делает то же самое. Так что вы можете просто написать:
for f in v2 {
Pin::from(f()).await;
}
PS : В своем комментарии ниже вы напишите этот код, чтобы дождаться фьючерса:
for f in v2 {
async { f().await }
}
Обратите внимание, что *Сам блок 1050 * оценивает другое будущее, поэтому здесь вы просто заключаете каждое будущее в другое будущее, но никто его не ждет. На самом деле вы получите предупреждение об этом:
предупреждение: неиспользуемый реализатор std::future::Future
, который необходимо использовать.
Помните, что для правильного ожидания всехфьючерсы вам понадобится асинхронная среда выполнения.