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