@@ -4,3 +4,119 @@ description: "Common design patterns in Rust"
4
4
duration : 30 minutes
5
5
---
6
6
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