Remove old section

This commit is contained in:
Philipp Oppermann
2020-02-25 14:20:26 +01:00
parent 868a6f03ec
commit 58faf5adf0

View File

@@ -488,97 +488,9 @@ Note that this function does not start the execution of the state machine. This
### Pinning
### The Async Keyword
The purpose of the async/await pattern is to make working with futures easier. Rust has language-level support for this pattern built on the two keywords `async` and `await`. We will explain them individually, starting with `async`.
The purpose of the `async` keyword is to turn a synchronous function into an asynchronous function that returns a `Future`:
```rust
fn synchronous() -> u32 {
42
}
async fn asynchronous() -> u32 {
42
}
```
While both functions specify a return type of `u32`, the `async` keyword turns the return type of the second function into `impl Future<Output = u32>`. So instead of returning an `u32` directly, the `asynchronous` function returns a type that implements the `Future` trait with output type `u32`. We can see this when we try to assign the result to a variable of type `u32`:
```rust
let val: u32 = asynchronous();
```
The compiler responds with the following error ([try it on the playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=590273d2f4ef75eb890c5354f788e29c)):
```
error[E0308]: mismatched types
--> src/main.rs:3:23
|
3 | let val: u32 = asynchronous();
| --- ^^^^^^^^^^^^^^ expected `u32`, found opaque type
| |
| expected due to this
...
10 | async fn asynchronous() -> u32 {
| --- the `Output` of this `async fn`'s found opaque type
|
= note: expected type `u32`
found opaque type `impl std::future::Future`
```
The relevant part of that error message are the last two lines: It expects an `u32` because of the type annotation, but the function returned an implementation of the `Future` trait instead.
Of course, changing the return type alone would not work. Instead, the compiler also needs to convert the function body, which is `42` in our case, into a future. Since `42` is not asynchronous, the compiler just generates a future that returns the result on the first `poll`. The generated code _could_ look something like this:
```rust
struct GeneratedFuture;
impl Future for GeneratedFuture {
type Output = u32;
fn poll(self: Pin<&mut Self>, _cx: &mut Context) -> Poll<Self::Output> {
Poll::Ready(42)
}
}
fn asynchronous() -> impl Future<Output = u32> {
GeneratedFuture
}
```
Instead of returning `u32`, the `asynchronous` function now returns an instance of a new `GeneratedFuture` struct. This struct implements the `Future` trait by returning `Poll::Ready(42)` on `poll`. The `42` is the body of `asynchronous` in this case.
Note that this is just an example implementation. The actual code generated by the compiler uses a much more powerful approach, which we will explain in a moment.
In addition to `async` futures, Rust also supports `async` blocks:
```rust
let future = async {
42
};
```
The `future` variable also has the type `impl Future<Output = u32>` in this case. The generated code is very similar to the `async fn`, only without a function call: `let future = GeneratedFuture;`.
We now know roughly what the `async` keyword does, but we still don't know why it's useful yet. After all, there is no advantage of returning a `impl Future<Output = u32>` instead of returning the `u32` directly. To answer this question, we have to explore different ways to work with futures.
#### Await
### Generators
### Executors
## Implementation