Skip to content

Commit 310cda6

Browse files
committed
use rust code blocks for consistent style
1 parent ddb11bf commit 310cda6

File tree

1 file changed

+33
-25
lines changed

1 file changed

+33
-25
lines changed

docs/src/concepts/futures.md

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -50,36 +50,42 @@ Remember the talk about "deferred computation" in the intro? That's all it is. I
5050

5151
Let's have a look at a simple function, specifically the return value:
5252

53-
fn read_file(path: &str) -> Result<String, io::Error> {
54-
let mut file = File.open(path)?;
55-
let mut contents = String::new();
56-
file.read_to_string(&mut contents)?;
57-
contents
58-
}
53+
```rust
54+
fn read_file(path: &str) -> Result<String, io::Error> {
55+
let mut file = File.open(path)?;
56+
let mut contents = String::new();
57+
file.read_to_string(&mut contents)?;
58+
contents
59+
}
60+
```
5961

6062
You can call that at any time, so you are in full control on when you call it. But here's the problem: the moment you call it, you transfer control to the called function until it returns a value - eventually.
6163
Note that this return value talks about the past. The past has a drawback: all decisions have been made. It has an advantage: the outcome is visible. We can unwrap the results of the program's past computation, and then decide what to do with it.
6264

6365
But we wanted to abstract over *computation* and let someone else choose how to run it. That's fundamentally incompatible with looking at the results of previous computation all the time. So, let's find a type that *describes* a computation without running it. Let's look at the function again:
6466

65-
fn read_file(path: &str) -> Result<String, io::Error> {
66-
let mut file = File.open(path)?;
67-
let mut contents = String::new();
68-
file.read_to_string(&mut contents)?;
69-
contents
70-
}
67+
```rust
68+
fn read_file(path: &str) -> Result<String, io::Error> {
69+
let mut file = File.open(path)?;
70+
let mut contents = String::new();
71+
file.read_to_string(&mut contents)?;
72+
contents
73+
}
74+
```
7175

7276
Speaking in terms of time, we can only take action *before* calling the function or *after* the function returned. This is not desirable, as it takes from us the ability to do something *while* it runs. When working with parallel code, this would take from us the ability to start a parallel task while the first runs (because we gave away control).
7377

7478
This is the moment where we could reach for [threads](https://en.wikipedia.org/wiki/Thread_). But threads are a very specific concurrency primitive and we said that we are searching for an abstraction.
7579

7680
What we are searching for is something that represents ongoing work towards a result in the future. Whenever we say "something" in Rust, we almost always mean a trait. Let's start with an incomplete definition of the `Future` trait:
7781

78-
trait Future {
79-
type Output;
80-
81-
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>;
82-
}
82+
```rust
83+
trait Future {
84+
type Output;
85+
86+
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output>;
87+
}
88+
```
8389

8490
Looking at it closely, we see the following:
8591

@@ -99,14 +105,16 @@ Note that calling `poll` after case 1 happened may result in confusing behaviour
99105

100106
While the `Future` trait has existed in Rust for a while, it was inconvenient to build and describe them. For this, Rust now has a special syntax: `async`. The example from above, implemented with `async-std`, would look like this:
101107

102-
use async_std::fs::File;
103-
104-
async fn read_file(path: &str) -> Result<String, io::Error> {
105-
let mut file = File.open(path).await?;
106-
let mut contents = String::new();
107-
file.read_to_string(&mut contents).await?;
108-
contents
109-
}
108+
```rust
109+
use async_std::fs::File;
110+
111+
async fn read_file(path: &str) -> Result<String, io::Error> {
112+
let mut file = File.open(path).await?;
113+
let mut contents = String::new();
114+
file.read_to_string(&mut contents).await?;
115+
contents
116+
}
117+
```
110118

111119
Amazingly little difference, right? All we did is label the function `async` and insert 2 special commands: `.await`.
112120

0 commit comments

Comments
 (0)