magical markdown slides
1---
2theme: default
3author: Learn Rust
4---
5
6# Learn Rust
7
8A quick tour through Rust fundamentals
9
10---
11
12## Comments
13
14Rust supports multiple comment styles:
15
16```rust
17// Line comments look like this
18// and extend multiple lines
19
20/* Block comments
21 /* can be nested. */ */
22
23/// Documentation comments support markdown
24/// # Examples
25/// ```
26/// let five = 5
27/// ```
28```
29
30---
31
32## Functions
33
34Functions use `fn` keyword with type annotations:
35
36```rust
37fn add2(x: i32, y: i32) -> i32 {
38 // Implicit return (no semicolon)
39 x + y
40}
41```
42
43**Key points:**
44
45- `i32` is a 32-bit signed integer
46- Last expression without `;` is the return value
47- Function parameters must have type annotations
48
49---
50
51## Variables
52
53Rust has immutable bindings by default:
54
55```rust
56// Immutable binding
57let x: i32 = 1;
58
59// Type inference works most of the time
60let implicit_x = 1;
61let implicit_f = 1.3;
62
63// Mutable variable
64let mut mutable = 1;
65mutable = 4;
66mutable += 2;
67```
68
69> [!TIP]
70> Variables are immutable by default - use `mut` only when you need to change values
71
72---
73
74## Numbers
75
76Integer and float types with suffixes:
77
78```rust
79// Integer/float suffixes
80let y: i32 = 13i32;
81let f: f64 = 1.3f64;
82
83// Arithmetic
84let sum = x + y + 13;
85```
86
87---
88
89## Strings
90
91Two main string types in Rust:
92
93```rust
94// String slice (&str) - immutable view
95let x: &str = "hello world!";
96
97// String - heap-allocated, growable
98let s: String = "hello world".to_string();
99
100// String slice from String
101let s_slice: &str = &s;
102
103// Printing
104println!("{} {}", f, x);
105```
106
107---
108
109## Arrays and Vectors
110
111Fixed-size arrays and dynamic vectors:
112
113```rust
114// Fixed-size array
115let four_ints: [i32; 4] = [1, 2, 3, 4];
116
117// Dynamic vector
118let mut vector: Vec<i32> = vec![1, 2, 3, 4];
119vector.push(5);
120
121// Slice - immutable view
122let slice: &[i32] = &vector;
123
124// Debug printing
125println!("{:?} {:?}", vector, slice);
126```
127
128---
129
130## Tuples
131
132Fixed-size sets of values of possibly different types:
133
134```rust
135// Tuple declaration
136let x: (i32, &str, f64) = (1, "hello", 3.4);
137
138// Destructuring
139let (a, b, c) = x;
140println!("{} {} {}", a, b, c); // 1 hello 3.4
141
142// Indexing
143println!("{}", x.1); // hello
144```
145
146---
147
148## Structs
149
150Custom data types with named fields:
151
152```rust
153struct Point {
154 x: i32,
155 y: i32,
156}
157
158let origin: Point = Point { x: 0, y: 0 };
159
160// Tuple struct (unnamed fields)
161struct Point2(i32, i32);
162let origin2 = Point2(0, 0);
163```
164
165---
166
167## Enums
168
169Enums can have variants with or without data:
170
171```rust
172// Basic C-like enum
173enum Direction {
174 Left,
175 Right,
176 Up,
177 Down,
178}
179
180let up = Direction::Up;
181
182// Enum with fields
183enum OptionalI32 {
184 AnI32(i32),
185 Nothing,
186}
187
188let two: OptionalI32 = OptionalI32::AnI32(2);
189```
190
191---
192
193## Generics
194
195Type parameters for reusable code:
196
197```rust
198struct Foo<T> { bar: T }
199
200enum Optional<T> {
201 SomeVal(T),
202 NoVal,
203}
204```
205
206The standard library provides `Option<T>` for optional values, replacing null pointers.
207
208---
209
210## Methods
211
212Functions associated with types:
213
214```rust
215impl<T> Foo<T> {
216 // Borrowed self
217 fn bar(&self) -> &T {
218 &self.bar
219 }
220
221 // Mutably borrowed self
222 fn bar_mut(&mut self) -> &mut T {
223 &mut self.bar
224 }
225
226 // Consumed self
227 fn into_bar(self) -> T {
228 self.bar
229 }
230}
231```
232
233---
234
235## Traits
236
237Interfaces that define shared behavior:
238
239```rust
240trait Frobnicate<T> {
241 fn frobnicate(self) -> Option<T>;
242}
243
244impl<T> Frobnicate<T> for Foo<T> {
245 fn frobnicate(self) -> Option<T> {
246 Some(self.bar)
247 }
248}
249
250let foo = Foo { bar: 1 };
251println!("{:?}", foo.frobnicate()); // Some(1)
252```
253
254---
255
256## Pattern Matching
257
258Powerful control flow with `match`:
259
260```rust
261let foo = OptionalI32::AnI32(1);
262match foo {
263 OptionalI32::AnI32(n) => println!("it's an i32: {}", n),
264 OptionalI32::Nothing => println!("it's nothing!"),
265}
266```
267
268---
269
270## Advanced Pattern Matching
271
272Destructure and use guards:
273
274```rust
275struct FooBar { x: i32, y: OptionalI32 }
276let bar = FooBar { x: 15, y: OptionalI32::AnI32(32) };
277
278match bar {
279 FooBar { x: 0, y: OptionalI32::AnI32(0) } =>
280 println!("The numbers are zero!"),
281 FooBar { x: n, y: OptionalI32::AnI32(m) } if n == m =>
282 println!("The numbers are the same"),
283 FooBar { x: n, y: OptionalI32::AnI32(m) } =>
284 println!("Different numbers: {} {}", n, m),
285 FooBar { x: _, y: OptionalI32::Nothing } =>
286 println!("The second number is Nothing!"),
287}
288```
289
290---
291
292## For Loops
293
294Iterate over arrays and ranges:
295
296```rust
297// Array iteration
298let array = [1, 2, 3];
299for i in array {
300 println!("{}", i);
301}
302
303// Range iteration
304for i in 0u32..10 {
305 print!("{} ", i);
306}
307// prints: 0 1 2 3 4 5 6 7 8 9
308```
309
310---
311
312## If Expressions
313
314`if` can be used as an expression:
315
316```rust
317if 1 == 1 {
318 println!("Maths is working!");
319} else {
320 println!("Oh no...");
321}
322
323// if as expression
324let value = if true {
325 "good"
326} else {
327 "bad"
328};
329```
330
331---
332
333## Loops
334
335Multiple loop constructs:
336
337```rust
338// while loop
339while condition {
340 println!("Looping...");
341 break // Exit the loop
342}
343
344// Infinite loop
345loop {
346 println!("Hello!");
347 break // Must break explicitly
348}
349```
350
351---
352
353## Owned Pointers (Box)
354
355`Box<T>` provides heap allocation with single ownership:
356
357```rust
358let mut mine: Box<i32> = Box::new(3);
359*mine = 5; // dereference
360
361// Ownership transfer (move)
362let mut now_its_mine = mine;
363*now_its_mine += 2;
364
365println!("{}", now_its_mine); // 7
366// println!("{}", mine); // Error! moved
367```
368
369When `Box` goes out of scope, memory is automatically deallocated.
370
371---
372
373## Immutable References
374
375Borrowing without transferring ownership:
376
377```rust
378let mut var = 4;
379var = 3;
380let ref_var: &i32 = &var;
381
382println!("{}", var); // Still works!
383println!("{}", *ref_var); // 3
384
385// var = 5; // Error! var is borrowed
386// *ref_var = 6; // Error! immutable reference
387
388ref_var; // Use the reference
389var = 2; // Borrow ended, can mutate again
390```
391
392---
393
394## Mutable References
395
396Exclusive mutable access:
397
398```rust
399let mut var2 = 4;
400let ref_var2: &mut i32 = &mut var2;
401*ref_var2 += 2;
402
403println!("{}", *ref_var2); // 6
404
405// var2 = 2; // Error! var2 is mutably borrowed
406
407ref_var2; // Use ends here
408// Now var2 can be used again
409```
410
411> [!WARNING]
412> Only ONE mutable reference OR many immutable references at a time
413
414---
415
416## Memory Safety
417
418> [!IMPORTANT]
419> Rust's borrow checker ensures memory safety at compile time
420
421Guarantees:
422
423- No use after free
424- No double free
425- No data races
426- No dangling pointers
427
428All at **compile time** with **zero runtime cost**.
429
430---
431
432## Next Steps
433
434- Explore the [Rust Book](https://doc.rust-lang.org/book/)
435- Try [Rust by Example](https://doc.rust-lang.org/rust-by-example/)
436- Practice with [Rustlings](https://github.com/rust-lang/rustlings)
437- Join the [Rust community](https://www.rust-lang.org/community)
438
439---
440
441## Thank You
442
443Happy Rusting!