#rust #rust-tokio
#Ржавчина
Вопрос:
Я пытаюсь изучить асинхронное программирование, но этот очень простой пример не работает:
use std::future::Future;
fn main() {
let t = async {
println!("Hello, world!");
};
t.poll();
}
Все, что я прочитал из спецификаций, говорит, что это должно сработать, но cargo жалуется, что метод «опрос» не может быть найден в «impl std :: future:: Future». Что я делаю не так?
Комментарии:
1. Что именно вы пытаетесь сделать со своим кодом? Обычно вы не будете использовать
.poll
напрямую при написании асинхронных приложений, вместо этого вы будете использоватьawait
методы или изFutureExt
.2. В основном я просто изучаю, как работает система. Я не могу использовать await в неасинхронном контексте, поэтому я пытаюсь выяснить, как вызвать асинхронный метод в неасинхронном контексте.
Ответ №1:
poll
имеет эту подпись:
fn poll(self: Pin<amp;mut Self>, cx: amp;mut Context<'_>) -> Poll<Self::Output>;
Есть две проблемы с вызовом этого так, как вы это делаете:
poll
реализуется не в будущемFut
, а вPin<amp;mut Fut>
будущем, поэтому сначала вам нужно получить закрепленную ссылку.pin_mut!
часто бывает полезен, и если future реализуетUnpin
, выPin::new
также можете использовать.- Однако большая проблема заключается в том, что
poll
принимаетamp;mut Context<'_>
аргумент. Контекст создается асинхронной средой выполнения и передается вpoll
функцию самого внешнего будущего. Это означает, что вы не можете просто опросить будущее таким образом, для этого вам нужно быть в асинхронной среде выполнения.
Вместо этого вы можете использовать ящик типа tokio
или async-std
для запуска future в синхронном контексте:
// tokio
use tokio::runtime::Runtime;
let runtime = Runtime::new().unwrap();
let result = runtime.block_on(async {
// ...
});
// async-std
let result = async_std::task::block_on(async {
// ...
})
Или, что еще лучше, вы можете использовать #[tokio::main]
или #[async_std::main]
для преобразования вашей main
функции в асинхронную функцию:
// tokio
#[tokio::main]
async fn main() {
// ...
}
// async-std
#[async_std::main]
async fn main() {
// ...
}