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!