Open the Cargo.toml file that has been generated earlier for you.
In the bin folder, create a file called generator.rs.
Add the following code, and run it with cargo run --bin generator:
1 #![feature(generators, generator_trait, conservative_impl_trait)]
2
3 fn main() {
4 // A closure that uses the keyword "yield" is called a generator
5 // Yielding a value "remembers" where you left off
6 // when calling .resume() on the generator
7 let mut generator = || {
8 yield 1;
9 yield 2;
10 };
11 if let GeneratorState::Yielded(value) = generator.resume() {
12 println!("The generator yielded: {}", value);
13 }
14 if let GeneratorState::Yielded(value) = generator.resume() {
15 println!("The generator yielded: {}", value);
16 }
17 // When there is nothing left to yield,
18 // a generator will automatically return an empty tuple
19 if let GeneratorState::Complete(value) = generator.resume() {
20 println!("The generator completed with: {:?}", value);
21 }
22
23 // At the moment, you can return a different type
24 // than you yield, although this feature is considered for removal
25 let mut generator = || {
26 yield 100;
27 yield 200;
28 yield 300;
29 "I'm a string"
30 };
31 loop {
32 match generator.resume() {
33 GeneratorState::Yielded(value) => println!("The generator yielded: {}", value),
34 GeneratorState::Complete(value) => {
35 println!("The generator completed with: {}", value);
36 break;
37 }
38 }
39 }
40
41 // Generators are great for implementing iterators.
42 // Eventually, all Rust iterators are going to be rewritten with generators
43 let fib: Vec<_> = fibonacci().take(10).collect();
44 println!("First 10 numbers of the fibonacci sequence: {:?}", fib);
45 }
46
47 // As of the time of writing, a generator does not have a
48 // direct conversion to an iterator yet, so we need a wrapper:
49 use std::ops::{Generator, GeneratorState};
50 struct GeneratorIterator(T);
51 impl Iterator for GeneratorIterator
52 where
53 T: Generator,
54 {
55 type Item = T::Yield;
56 fn next(&mut self) -> Option {
57 match self.0.resume() {
58 GeneratorState::Yielded(value) => Some(value),
59 GeneratorState::Complete(_) => None,
60 }
61 }
62 }
63
64 fn fibonacci() -> impl Iterator {
65 // Using our wrapper
66 GeneratorIterator(move || {
67 let mut curr = 0;
68 let mut next = 1;
69 loop {
70 yield curr;
71 let old = curr;
72 curr = next;
73 next += old;
74 }
75 })
76 }