Structs & Enums
Structs and enums are Rust's tools for creating custom data types. They allow you to group related data together and define behavior through methods. This section will teach you how to model your domain effectively using Rust's type system.
What You'll Learn
This section covers Rust's custom data types and their capabilities:
Data Modeling
- Structs - Group related data into custom types with named fields
- Enums & Pattern Matching - Model data that can be one of several variants
- Methods & Associated Functions - Add behavior to your custom types
- Option & Result - Handle null values and errors safely with Rust's standard enums
Why Custom Types Matter
Custom data types provide several benefits:
- Code Organization - Group related data and behavior together
- Type Safety - Prevent invalid data combinations at compile time
- Expressiveness - Model your domain clearly and accurately
- Performance - Zero-cost abstractions with compile-time guarantees
Learning Path
Follow this progression for the best understanding:
- Structs - Create custom types with named fields
- Enums & Pattern Matching - Model variants and match on them
- Methods & Associated Functions - Add behavior to your types
- Option & Result - Master Rust's approach to null values and error handling
Key Concepts
By the end of this section, you'll be able to:
- Design structs to represent complex data
- Use tuple structs and unit structs appropriately
- Create enums with data-carrying variants
- Write comprehensive pattern matching expressions
- Implement methods and associated functions
- Handle optional values with
Option<T>
- Manage errors elegantly with
Result<T, E>
Common Patterns
Here are some fundamental patterns you'll learn:
// Struct with named fields
struct User {
username: String,
email: String,
active: bool,
}
// Enum with data variants
enum Message {
Quit,
Move { x: i32, y: i32 },
Write(String),
ChangeColor(i32, i32, i32),
}
// Implementation block with methods
impl User {
// Associated function (constructor)
fn new(username: String, email: String) -> User {
User {
username,
email,
active: true,
}
}
// Method that borrows self
fn is_active(&self) -> bool {
self.active
}
// Method that mutates self
fn deactivate(&mut self) {
self.active = false;
}
}
// Pattern matching on enums
fn process_message(msg: Message) {
match msg {
Message::Quit => println!("Quit"),
Message::Move { x, y } => println!("Move to ({}, {})", x, y),
Message::Write(text) => println!("Text: {}", text),
Message::ChangeColor(r, g, b) => println!("Color: ({}, {}, {})", r, g, b),
}
}
// Working with Option and Result
fn divide(a: f64, b: f64) -> Option<f64> {
if b != 0.0 {
Some(a / b)
} else {
None
}
}
fn safe_divide(a: f64, b: f64) -> Result<f64, String> {
if b != 0.0 {
Ok(a / b)
} else {
Err("Division by zero".to_string())
}
}
Prerequisites
Before diving into structs and enums, you should be comfortable with:
- Basic Rust syntax and ownership rules
- Functions and variable declarations
- Pattern matching with
match
expressions
If you need to review these concepts, check out:
- Rust Basics for syntax and functions
- Ownership & Borrowing for understanding how custom types work with ownership
Real-World Applications
You'll learn to model common scenarios like:
- User profiles with personal information and preferences
- Configuration settings with different option types
- HTTP responses that can be successful or contain errors
- Game states with different phases and data
- File operations that might succeed or fail
- API responses with optional and required fields
What Comes Next
After mastering structs and enums, you'll be ready for:
- Advanced Features - Traits to define shared behavior across types
- Error Handling - Advanced error handling patterns
- Generics - Make your structs and enums work with multiple types
Design Philosophy
Rust encourages "making invalid states unrepresentable" through its type system. You'll learn to:
- Use enums to model mutually exclusive states
- Leverage the compiler to catch logic errors
- Design APIs that are hard to misuse
- Express business rules through types
Ready to create powerful custom types? Start with Structs!