This content originally appeared on DEV Community and was authored by Lymah
Welcome back to Week 3 of my Rust learning journey! Last week, I focused on structuring data with compound types and guiding program flow. This week felt like unlocking a new level. I dove into pattern matching, match
/if let
, and how methods work in Rust (yes, Rust has methods!).
Here's what I tackled:
- Pattern Matching:
-
match
expressions -
matches!
macro -
if let
expressions - Understanding various Patterns
-
- Methods & Associated Functions
Let's dive into how these concepts are elevating my Rust code, and how my AI assistant is evolving into an even smarter partner in this learning process.
1. Pattern Matching
This was definitely the highlight of the week. Rust's pattern matching allows for incredibly concise and safe ways to handle different data variations, especially with enums. It feels so much more robust than chained if/else
statements.
match
Expressions
- Rust’s
match
is more powerful than what I’ve used in other languages. - You can match enums, primitives, structs, even nested patterns.
Examples
match some_number {
1 => println!("One!"),
2 | 3 => println!("Two or three"),
4..=10 => println!("Between four and ten"),
_ => println!("Something else"),
}
enum Coin {
Penny,
Nickel,
Dime,
Quarter(UsState), // Enum variant with associated data
}
enum UsState { // For our Quarter example
Alabama,
Alaska,
// ... many more states
California,
}
fn value_in_cents(coin: Coin) -> u8 {
match coin {
Coin::Penny => { // Code block for Penny
println!("Lucky Penny!");
1
},
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter(state) => { // Destructure associated data
println!("State quarter from {:?}!", state);
25
},
}
}
fn main() {
println!("Value of a Quarter: {}", value_in_cents(Coin::Quarter(UsState::California)));
println!("Value of a Penny: {}", value_in_cents(Coin::Penny));
}
I love how it enforces exhaustiveness. Rust forces you to think clearly.
matches!
The matches! macro is fantastic for a quick boolean check if a value matches a pattern, without extracting the value.
Quick and clean way to check if a value matches a specific pattern
Examples
if matches!(x, Some(_)) {
println!("It’s Some!");
}
fn main() {
let coin = Coin::Quarter(UsState::Alabama);
if matches!(coin, Coin::Quarter(_)) { // Does coin match any Quarter variant?
println!("It's definitely a quarter!");
}
if matches!(coin, Coin::Quarter(UsState::Alabama)) { // Does it match a Quarter from Alabama?
println!("Specifically an Alabama Quarter!");
}
if !matches!(coin, Coin::Penny) {
println!("Definitely not a penny.");
}
}
I used this to simplify conditions that felt too heavy with
match
.
if let
When you only care about one specific variant of an enum or a single pattern, if let
is a cleaner alternative to a full match expression.
Great when you only care about one pattern.
Examples
if let Some(val) = option {
println!("Got a value: {}", val);
}
fn main() {
let config_max = Some(3u8);
if let Some(max) = config_max { // If config_max matches Some(max)
println!("The maximum is: {}", max);
} else {
println!("No maximum configured.");
}
let coin = Coin::Dime; // Using the Coin enum from above
if let Coin::Quarter(state) = coin {
println!("It's a quarter from {:?}", state);
} else {
println!("It's not a quarter.");
}
}
Clean, but I learned it can hide unmatched variants, so I’m using it carefully.
Patterns (The Building Blocks of Matching)
Understanding the various types of patterns is key to leveraging match
and if let
. I explored:
-
Literals:
match x { 1 => ... }
-
Named Variables:
match x { some_var => ... }
(these bind the value) -
Wildcards:
match x { _ => ... }
(ignore the value) - _ placeholder: For unused variables.
-
Ranges:
match x { 1..=5 => ... }
-
Enums:
match coin { Coin::Penny => ... }
-
Structs:
match user { User { username, .. } => ... }
(destructuring!) -
Tuples:
match point { (x, y) => ... }
(destructuring!) -
References:
match &value { &10 => ... }
(matching on a reference)
Learning to combine these patterns for complex scenarios is a journey, and the compiler is a great guide
2. Methods & Associated Functions
This was a very satisfying part of the week, as it allowed me to start making my custom struct
s and enum
s truly behave like "objects" (in a Rust sense, not OOP).
Methods: &self
, &mut self
, self
Methods are functions defined on a struct or enum using an impl
block, and they take self
as their first parameter. The choice of self
(&self
, &mut self
, self
) dictates whether the method borrows immutably, borrows mutably, or takes ownership of the instance. This ties directly back to Week 1's ownership and borrowing rules!
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// Method that immutably borrows `self`
fn area(&self) -> u32 {
self.width * self.height
}
// Method that mutably borrows `self`
fn set_width(&mut self, new_width: u32) {
self.width = new_width;
}
// Method that takes ownership of `self`
fn consume_and_describe(self) {
println!("Consuming a rectangle of {}x{}", self.width, self.height);
// `self` is dropped here, so you can't use it afterwards
}
}
fn main() {
let mut rect1 = Rectangle { width: 30, height: 50 };
println!("Initial area: {}", rect1.area()); // Calling an immutable method
rect1.set_width(40); // Calling a mutable method
println!("New width: {}", rect1.width);
rect1.consume_and_describe(); // This consumes rect1
// println!("Can't use rect1 after consumption: {}", rect1.width); // Error!
}
Associated Functions
Associated functions are also defined in impl
blocks, but they don't take self
as their first parameter. They're often used as constructors or utility functions related to the type, similar to static methods in other languages.
impl Rectangle {
// Associated function (constructor)
fn square(size: u32) -> Rectangle {
Rectangle { width: size, height: size }
}
}
fn main() {
let sq = Rectangle::square(25); // Calling an associated function
println!("Square area: {}", sq.area());
}
My AI Assistant Insight: When I needed to remember the exact syntax for defining a method vs. an associated function, or the difference between &self
, &mut self
, and self
, a quick prompt like "Rust method with mutable self vs immutable self"
immediately gave me the right examples and explanations. It’s like having the Rust docs indexed for my specific questions.
Learning by Doing: More Rust by Example Immersion
My primary learning tool continues to be Rust by example (https://doc.rust-lang.org/rust-by-example/). I diligently worked through all the exercises and examples in the "Pattern Matching," "Methods," and "Associated Functions" sections this week.
This hands-on practice was absolutely critical for internalizing these concepts:
-
Encountering Match Exhaustiveness: The compiler quickly reminded me if I missed a case in a
match
expression, which was a great learning experience. -
Borrowing Rules with Methods: Practicing methods that take
&self
and&mut self
really solidified my understanding of ownership and borrowing from Week 1. -
Syntax Muscle Memory: Repeatedly writing
impl
blocks and various patterns helped build muscle memory for Rust's syntax.
Week 3 Reflections
This week was incredibly satisfying. Pattern matching is a powerful paradigm that makes Rust code both safer (due to exhaustiveness checks) and more readable. Defining methods and associated functions brought a new level of organization and functionality to my custom data types. The interplay between these new concepts and the core ownership/borrowing rules from Week 1 is becoming clearer.
My AI assistant is now less about "what does this keyword do?" and more about "how can I apply this concept idiomatically?" or "show me a more advanced example of this pattern." It's accelerating my understanding of best practices and complex syntax, allowing me to explore more deeply than I might on my own.
What's your favorite use case for match expressions, or a powerful method you've written in Rust? Share your insights below!
This content originally appeared on DEV Community and was authored by Lymah

Lymah | Sciencx (2025-06-11T03:35:56+00:00) 🦀 Week 3 of Learning Rust: Match, Patterns, and the Power of Methods. Retrieved from https://www.scien.cx/2025/06/11/%f0%9f%a6%80-week-3-of-learning-rust-match-patterns-and-the-power-of-methods/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.