Rust: метод «опрос» не найден в `impl std :: future :: Future`

#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>;
 

Есть две проблемы с вызовом этого так, как вы это делаете:

  1. poll реализуется не в будущем Fut , а в Pin<amp;mut Fut> будущем, поэтому сначала вам нужно получить закрепленную ссылку. pin_mut! часто бывает полезен, и если future реализует Unpin , вы Pin::new также можете использовать.
  2. Однако большая проблема заключается в том, что 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() {
  // ...
}