Futures

Future is a trait, implemented by objects that represent an operation that may not be complete yet. A future can be polled, and poll returns a Poll.

  1. #![allow(unused)]
  2. fn main() {
  3. use std::pin::Pin;
  4. use std::task::Context;
  5. pub trait Future {
  6.     type Output;
  7.     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>;
  8. }
  9. pub enum Poll<T> {
  10.     Ready(T),
  11.     Pending,
  12. }
  13. }

An async function returns an impl Future. It’s also possible (but uncommon) to implement Future for your own types. For example, the JoinHandle returned from tokio::spawn implements Future to allow joining to it.

The .await keyword, applied to a Future, causes the current async function to pause until that Future is ready, and then evaluates to its output.

This slide should take about 4 minutes.

  • The Future and Poll types are implemented exactly as shown; click the links to show the implementations in the docs.

  • We will not get to Pin and Context, as we will focus on writing async code, rather than building new async primitives. Briefly:

    • Context allows a Future to schedule itself to be polled again when an event occurs.

    • Pin ensures that the Future isn’t moved in memory, so that pointers into that future remain valid. This is required to allow references to remain valid after an .await.