👋 Hello World
fn main() {
println!("Hello, world!");
}
💡 Tip: Use println!
macro for output in Rust.
📦 Variables & Data Types
fn main() {
let age: i32 = 21;
let pi: f64 = 3.14159;
let grade: char = 'A';
let name: &str = "Maxon";
println!("{} is {} years old.", name, age);
}
💡 Tip: Variables are immutable by default. Use mut
for mutability.
🔀 Control Flow
fn main() {
for i in 1..=5 {
if i % 2 == 0 {
println!("{} is even", i);
} else {
println!("{} is odd", i);
}
}
}
💡 Tip: Use if
, else if
, match
, loop
, and while
for control flow.
🛠 Functions
fn add(a: i32, b: i32) -> i32 {
a + b
}
fn main() {
println!("Sum: {}", add(5, 3));
}
💡 Tip: Functions return the last expression automatically (no return
needed).
🏗 Structs
struct Car {
brand: String,
speed: u32,
}
impl Car {
fn drive(&self) {
println!("{} drives at {} km/h", self.brand, self.speed);
}
}
fn main() {
let car = Car { brand: String::from("Tesla"), speed: 120 };
car.drive();
}
💡 Tip: Use impl
blocks to define methods on structs.
🧩 Enums
enum Direction {
Up,
Down,
Left,
Right,
}
fn main() {
let dir = Direction::Up;
match dir {
Direction::Up => println!("Going Up!"),
Direction::Down => println!("Going Down!"),
_ => println!("Left or Right!"),
}
}
💡 Tip: match
is exhaustive — all variants must be covered.
🔒 Ownership & Borrowing
fn main() {
let s1 = String::from("Hello");
let s2 = s1; // Ownership moved!
// println!("{}", s1); // ❌ Error: value borrowed after move
println!("{}", s2);
}
💡 Tip: Use &
for borrowing to avoid moving ownership.
📍 References
fn main() {
let x = 10;
let r = &x;
println!("Reference: {}", r);
}
💡 Tip: References (&
) do not take ownership. Use &mut
for mutable references.
🧠 Traits
trait Greet {
fn say_hello(&self);
}
struct Person {
name: String,
}
impl Greet for Person {
fn say_hello(&self) {
println!("Hello, {}!", self.name);
}
}
fn main() {
let p = Person { name: String::from("Maxon") };
p.say_hello();
}
💡 Tip: Traits are like interfaces in other languages.
📦 Generics
fn add<T: std::ops::Add<Output = T>>(a: T, b: T) -> T {
a + b
}
fn main() {
println!("{}", add(5, 3));
println!("{}", add(2.5, 1.2));
}
💡 Tip: Generics let you write flexible, type-safe code.
📚 Collections
use std::collections::HashMap;
fn main() {
let mut nums = vec![1, 2, 3];
nums.push(4);
println!("{:?}", nums);
let mut scores = HashMap::new();
scores.insert("Alice", 90);
scores.insert("Bob", 85);
println!("{:?}", scores);
}
💡 Tip: Common collections: Vec
, HashMap
, HashSet
.
📂 File Handling
use std::fs::File;
use std::io::prelude::*;
fn main() -> std::io::Result<()> {
let mut file = File::create("data.txt")?;
file.write_all(b"Hello File!")?;
let mut f = File::open("data.txt")?;
let mut contents = String::new();
f.read_to_string(&mut contents)?;
println!("{}", contents);
Ok(())
}
💡 Tip: The ?
operator propagates errors easily.
⚡ Closures
fn main() {
let square = |x: i32| x * x;
println!("{}", square(5));
}
💡 Tip: Closures can capture variables from their environment.
🧠 Smart Pointers
use std::rc::Rc;
use std::cell::RefCell;
fn main() {
let value = Rc::new(RefCell::new(42));
*value.borrow_mut() += 1;
println!("{}", value.borrow());
}
💡 Tip: Use Rc
for reference counting and RefCell
for interior mutability.