2024-10-07
005 - Structs and Enums
Learning Rust as a Pythonista: Structs and Enums
This lesson covers Rust’s two core data modeling tools: struct and enum.
Why this matters for Python developers
dataclassandnamedtuplemap naturally to Ruststructs.- Rust
enums are much more powerful than PythonEnumbecause variants can carry data. - Together with
match, they make state modeling explicit and safe.
Learning goals
By the end of this lesson, you should be able to:
- Define and instantiate regular and tuple structs.
- Model multiple states with enums carrying data.
- Use
matchto handle enum variants exhaustively.
Concepts in 5 minutes
struct= named fields- tuple struct = positional fields with custom type identity
enum= one of several variants (each variant may carry different data)match= exhaustive branching over enum variants
Python baseline snippet
from dataclasses import dataclass
from enum import Enum
@dataclass
class Post:
id: int
title: str
class Status(Enum):
DRAFT = "draft"
PUBLISHED = "published"
Rust equivalent snippets
struct Post {
id: u64,
title: String,
}
struct Rgb(u8, u8, u8);
enum PostStatus {
Draft,
Published { published_at: String },
Archived { reason: String },
}
One runnable end-to-end example
struct Post {
id: u64,
title: String,
views: u32,
}
struct Rgb(u8, u8, u8);
enum PostStatus {
Draft,
Published { published_at: String },
Archived { reason: String },
}
fn status_label(status: &PostStatus) -> String {
match status {
PostStatus::Draft => "draft".to_string(),
PostStatus::Published { published_at } => format!("published at {}", published_at),
PostStatus::Archived { reason } => format!("archived ({})", reason),
}
}
fn main() {
let mut post = Post {
id: 1,
title: "Learning Rust".to_string(),
views: 0,
};
post.views += 1;
println!("#{} {} (views: {})", post.id, post.title, post.views);
let accent = Rgb(52, 152, 219);
println!("theme color: {}, {}, {}", accent.0, accent.1, accent.2);
let states = [
PostStatus::Draft,
PostStatus::Published {
published_at: "2026-05-10".to_string(),
},
PostStatus::Archived {
reason: "superseded".to_string(),
},
];
for state in &states {
println!("status: {}", status_label(state));
}
}
Common mistakes
- Using structs where enums model state transitions better.
- Forgetting to handle all enum variants in
match. - Overusing tuple structs when named fields would be clearer.
Quick practice
- Add a
Scheduled { publish_at: String }variant and handle it instatus_label. - Add a method-like function
bump_views(post: &mut Post)and call it twice.
Recap
Use structs for data shape, enums for state/variants, and match to keep behavior explicit and exhaustive.
Next lesson: iterators and closures.
Join the Journey Ahead!
If you're eager to continue this learning journey and stay updated with the latest insights, consider subscribing. By joining our mailing list, you'll receive notifications about new articles, tips, and resources to help you seamlessly pick up Rust by leveraging your Python skills.
Other articles in the series
- 000 - Learning Rust as a Pythonista: A Suggested Path
- 001 - Your First Rust Program
- 002 - Basic Syntax and Structure
- 003 - Ownership, Borrowing, and Lifetimes
- 004 - Error Handling
- 006 - Iterators and Closures
- 007 - Traits vs Duck Typing and Protocols
- 008 - Concurrency in Rust for Python Developers
- 009 - Async Concurrency with Tokio
- 010 - Pattern Matching in Rust
- 011 - Macros in Rust