Rust Enums and match Explained: Variants, Data, Exhaustive Matching
November 10, 2026
Welcome to episode 12 of Rust for Beginners, a series for complete beginners (no programming experience needed). In the last video, we learned about methods. Today, we'll learn enums and match, one of the features people love most about Rust. Every code block below is the exact code from the video, ready to copy.
- All episodes are in the Rust Tutorial for Beginners playlist.
- Versions used: Rust 1.99.1 on Ubuntu, VS Code with rust-analyzer.
1. New project
Let's create a new project called enums, and open it in VS Code.
cargo new enums
cd enums2. enum
An enum is a type that can be one of a fixed list of values, called variants. A Coin is a penny, a nickel, a dime, or a quarter. Nothing else.
src/main.rs:
enum Coin {
Penny,
Nickel,
Dime,
Quarter,
}
fn value_in_cents(coin: Coin) -> u32 {
match coin {
Coin::Penny => 1,
Coin::Nickel => 5,
Coin::Dime => 10,
Coin::Quarter => 25,
}
}
fn main() {
println!("A dime is {} cents.", value_in_cents(Coin::Dime));
let mut total = 0;
for coin in [Coin::Penny, Coin::Nickel, Coin::Dime, Coin::Quarter] {
total += value_in_cents(coin);
}
println!("One of each: {total} cents.");
}Output: A dime is 10 cents. / One of each: 41 cents.
Error in step 7:
error[E0004]: non-exhaustive patterns: `Coin::Quarter` not covered
--> src/main.rs:9:11
|
9 | match coin {
| ^^^^ pattern `Coin::Quarter` not covered
|
note: `Coin` defined here
--> src/main.rs:1:6
|
1 | enum Coin {
| ^^^^
...
5 | Quarter,
| ------- not covered
= note: the matched value is of type `Coin`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
12 ~ Coin::Dime => 10,
13 ~ Coin::Quarter => todo!(),3. match
match compares a value against patterns, and runs the arm that fits. Each arm is a pattern, an arrow, and the result.
4. Expression
Like if, match is an expression. Here, its result is the return value of the function.
5. Run A
Let's run it. A dime is ten cents, and one of each makes forty-one.
cargo run6. Exhaustive
What happens if we forget a variant? Let's delete the quarter arm.
cargo run7. Error
Rust refuses: the quarter is not covered. match must handle every possible case. You can't forget one by accident.
8. Fix
Let's put it back.
cargo run9. Data
Enum variants can also hold data. A Circle holds its radius. A Rectangle holds a width and a height.
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn area(shape: Shape) -> f64 {
match shape {
Shape::Circle(radius) => 3.14 * radius * radius,
Shape::Rectangle(w, h) => w * h,
}
}
fn main() {
println!("Circle: {}", area(Shape::Circle(2.0)));
println!("Rectangle: {}", area(Shape::Rectangle(3.0, 4.0)));
}Output: Circle: 12.56 / Rectangle: 12
10. Bind
In match, we can pull that data out into variables, and use them right in the arm.
11. Run B
Let's run it.
cargo run12. Numbers
match works with numbers too. A vertical bar means "or", dot dot equals is a range, and the underscore matches anything else.
fn main() {
for number in [1, 3, 7, 42] {
let word = match number {
1 => "one",
2 | 3 => "two or three",
4..=9 => "a few",
_ => "many",
};
println!("{number}: {word}");
}
}Output: 1: one / 3: two or three / 7: a few / 42: many
13. Run C
Let's run it.
cargo runRecap
To recap: an enum is one of a fixed set of variants, which can carry data. match handles each case, and it must cover all of them. The underscore catches the rest.