TL;DR
- Struct = product type (all fields). Enum = sum type (one variant).
- Use
impl blocks for methods. self = instance, Self = type.
- Enums can hold data per variant. Pattern match with
match.
Structs
struct User {
name: String,
age: u32,
active: bool,
}
impl User {
// Constructor (associated function)
fn new(name: &str, age: u32) -> Self {
Self { name: name.to_string(), age, active: true }
}
// Method
fn greet(&self) -> String {
format!("Hi, I'm {} ({})", self.name, self.age)
}
}
Enums
enum Shape {
Circle(f64), // radius
Rectangle(f64, f64), // width, height
Triangle { base: f64, height: f64 },
}
impl Shape {
fn area(&self) -> f64 {
match self {
Shape::Circle(r) => std::f64::consts::PI * r * r,
Shape::Rectangle(w, h) => w * h,
Shape::Triangle { base, height } => 0.5 * base * height,
}
}
}
Key Patterns
| Pattern |
Use Case |
Option<T> |
Value that might not exist |
Result<T, E> |
Operation that can fail |
Newtype struct Id(u64) |
Type safety wrapper |
| Builder pattern |
Complex struct construction |