Skip to content

Commit 75a5dc1

Browse files
committed
advance module
1 parent 0ffb3dd commit 75a5dc1

File tree

3 files changed

+391
-5
lines changed

3 files changed

+391
-5
lines changed

syllabus/module/2.3-slides.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,4 +509,17 @@ impl Demo {
509509

510510
## macro_rules Transcribers
511511

512+
```rust
513+
// macro_rules transcribers
514+
macro_rules! demo {
515+
() => {
516+
println!("{}", format!("demo{}", '!'));
517+
};
518+
}
519+
520+
demo!();
521+
```
522+
523+
---
524+
512525

syllabus/module/2.4-slides.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,119 @@ description: "Common design patterns in Rust"
44
duration: 30 minutes
55
---
66

7+
## Overlapping Patterns
8+
9+
- Patterns easily overlap.
10+
- Minimize number of match arms to avoid bugs
11+
12+
```rust
13+
match slice {
14+
[first, ..] => (),
15+
[.., last] => (),
16+
[] => (),
17+
}
18+
19+
```
20+
21+
Second arm always ignored
22+
23+
---
24+
25+
## Prevent Overlapping Patterns
26+
27+
- Match the largest patterns first, followed by smaller patterns
28+
29+
```rust
30+
match slice {
31+
[] => (),
32+
[a, ..] => (),
33+
[a, b, ..] => (),
34+
[a, b, c, ..] => (),
35+
[a, b, c, d, ..] => (),
36+
}
37+
// "First two arms cover all cases, remaining will be ignored"
38+
match slice {
39+
[a, b, c, d, ..] => (),
40+
[a, b, c, ..] => (),
41+
[a, b, ..] => (),
42+
[a, ..] => (),
43+
[] => (),
44+
}
45+
// "All arms can be matched"
46+
47+
```
48+
49+
---
50+
51+
## Guards
52+
53+
```rust
54+
let nums = vec![7, 8, 9];
55+
match nums.as_slice() {
56+
[first @ 1..=3, rest @ ..] => {
57+
// 'first' is always 1, 2 or 3
58+
// 'rest' is the remaining slice
59+
},
60+
[single] if single == &5 || single == &6 => (),
61+
[a, b] => (),
62+
[..] => (),
63+
[] => (),
64+
}
65+
```
66+
67+
## Typestates Patterns
68+
69+
- Leverage type system to encode state changes
70+
- Implemented by creating a type for each state
71+
- Use move semantics to invalidate a state
72+
- Return next state from previous state
73+
- Optionally drop the state
74+
- Close file, connection dropped, etc
75+
- Compile time enforcement of logic
76+
77+
---
78+
79+
## Example
80+
81+
```rust
82+
struct BusTicket;
83+
struct BoardedBusTicket;
84+
85+
impl BusTicket {
86+
fn board(self) -> BoardedBusTicket {
87+
BoardedBusTicket
88+
}
89+
}
90+
91+
let ticket = BusTicket;
92+
let boarded = ticket.board();
93+
94+
// Compile error
95+
ticket.board();
96+
```
97+
98+
---
99+
100+
## Example
101+
102+
```rust
103+
struct File<'a>(&'a str);
104+
105+
impl<'a> File<'a> {
106+
fn read_bytes(&self) -> Vec<u8> {
107+
// ... read data ...
108+
}
109+
110+
fn delete(self) {
111+
// ... delete file ...
112+
}
113+
}
114+
115+
let file = File("data.txt");
116+
let data = file.read_bytes();
117+
file.delete();
118+
119+
// Compile error
120+
let read_again = file.read_bytes();
121+
122+
```

0 commit comments

Comments
 (0)