Question
I am coming from a Java background, where I might define an enum like this:
enum Direction {
NORTH, SOUTH, EAST, WEST
}
for (Direction dir : Direction.values()) {
// do something with dir
}
In Java, Direction.values() gives me all enum variants, and I can loop over them easily.
How can I do something similar with Rust enums? Is there a built-in way to iterate through all values of an enum, or is there a common Rust pattern for this?
Short Answer
By the end of this page, you will understand why Rust enums do not automatically provide a values() method like Java enums, and how to iterate over enum variants using common Rust patterns. You will also see practical examples, trade-offs, and how this is handled in real Rust codebases.
Concept
Rust enums and Java enums look similar at first, but they are designed differently.
In Java, enums are a special kind of class with built-in runtime support for listing all values using methods like values(). In Rust, an enum is a type that can represent one of several variants, but Rust does not automatically generate a list of all variants.
For example:
enum Direction {
North,
South,
East,
West,
}
This tells Rust that a Direction can be one of four variants. However, Rust does not keep a built-in array or registry of those variants for iteration.
Why? Because Rust enums are more general than Java enums:
- Variants can hold data
- Enums are often used for pattern matching, not just named constants
- Rust prefers explicitness over hidden runtime features
That means if you want to iterate over every variant, you usually choose one of these approaches:
- Define a constant array containing all variants
- Implement a helper method that returns all variants
- Use a crate such as
strumto derive iteration support
This matters in real programming when you need to:
- render all possible options in a UI
- validate user input against allowed values
- loop through states or directions in a game
- test all enum variants
So the core idea is: Rust does not provide enum iteration automatically, but it is easy to add using explicit patterns.
Mental Model
Think of a Rust enum like a set of labeled cards in a box.
- The enum definition tells you which cards are allowed.
- But Rust does not automatically hand you a stack containing one of each card.
- If you want to loop over them, you must prepare that stack yourself.
In Java, the language gives you the stack automatically with values().
In Rust, you usually create that stack explicitly, such as:
const ALL_DIRECTIONS: [Direction; 4] = [
Direction::North,
Direction::South,
Direction::East,
Direction::West,
];
Now you have a concrete collection to iterate over.
So the mental model is:
enumdefines the possible choices- an array or helper provides the iterable list of choices
Syntax and Examples
Basic pattern: define all variants in an array
A common beginner-friendly Rust approach is to store all enum variants in a constant array.
#[derive(Debug, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
}
const ALL_DIRECTIONS: [Direction; 4] = [
Direction::North,
Direction::South,
Direction::East,
Direction::West,
];
fn main() {
for dir in ALL_DIRECTIONS {
println!("{:?}", dir);
}
}
Why Clone and Copy?
For small enums without attached data, deriving Copy is convenient. It lets each value be copied cheaply when iterating.
Alternative: return a slice from an associated function
#[derive(Debug, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
}
impl Direction {
fn all() -> &'static [Direction] {
&[
Direction::North,
Direction::South,
Direction::East,
Direction::West,
]
}
}
() {
Direction::() {
(, dir);
}
}
Step by Step Execution
Consider this example:
#[derive(Debug, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
}
const ALL_DIRECTIONS: [Direction; 4] = [
Direction::North,
Direction::South,
Direction::East,
Direction::West,
];
fn main() {
for dir in ALL_DIRECTIONS {
println!("Moving {:?}", dir);
}
}
Here is what happens step by step:
enum Directiondefines four possible values.ALL_DIRECTIONScreates an array containing one of each variant.main()starts running.- The
forloop takes each item fromALL_DIRECTIONSone at a time. - On the first iteration,
dirisDirection::North. println!printsMoving North.- The loop repeats for
South,East, and .
Real World Use Cases
Iterating through enum variants is useful in many practical situations.
Building menu options
If your app has a list of available modes:
enum Theme {
Light,
Dark,
System,
}
You might loop through all themes to render a settings menu.
Game movement or state logic
A game may use directions such as North, South, East, and West to test possible moves.
Validation and parsing
You may want to compare user input against all allowed enum values and display valid options.
Testing all variants
When writing tests, iterating over all enum variants helps verify that every option behaves correctly.
Data export or reporting
If an enum represents categories, statuses, or roles, iterating over all variants can help generate reports or summaries.
Real Codebase Usage
In real Rust projects, developers usually use enum iteration in a few common patterns.
Configuration and option lists
An enum may represent a fixed set of supported values, such as log levels, themes, regions, or output formats. A helper like all() is often used to populate dropdowns, CLI help text, or config validation.
Validation
A request parser may convert strings into enum variants. If parsing fails, code can iterate through all valid values to build a useful error message.
Tests
Developers often iterate through every variant in tests to avoid missing edge cases.
#[test]
fn all_directions_have_labels() {
for dir in Direction::all() {
let label = match dir {
Direction::North => "North",
Direction::South => "South",
Direction::East => "East",
Direction::West => "West",
};
assert!(!label.is_empty());
}
}
Guarded APIs
Sometimes a public API exposes Direction::all() so other parts of the codebase have one consistent source of truth.
Crate-based derive patterns
Common Mistakes
Mistake 1: expecting a built-in values() method
This does not exist in Rust:
for dir in Direction::values() {
println!("{:?}", dir);
}
Fix
Create your own list of variants or use a crate like strum.
Mistake 2: forgetting to keep the manual list updated
Broken design:
#[derive(Debug, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
Up,
}
const ALL_DIRECTIONS: [Direction; 4] = [
Direction::North,
Direction::South,
Direction::East,
Direction::West,
];
Here, Up exists in the enum but is missing from the array.
Fix
Whenever you add a variant, update the array or use strum to avoid manual duplication.
Mistake 3: trying to iterate enums with data as if they were simple fixed values
enum {
Quit,
(, ),
(),
}
Comparisons
| Approach | How it works | Pros | Cons |
|---|---|---|---|
| Manual array constant | Store all variants in a constant array | Simple, no dependencies, easy to understand | Must be updated manually |
all() associated function | Return a slice or array from the enum impl | Clean API, keeps logic near enum | Still manual |
strum with EnumIter | Derive iteration support using a crate | Convenient, less repetition | Adds dependency |
Rust enums vs Java enums
| Feature | Java enum | Rust enum |
|---|---|---|
| Built-in list of values |
Cheat Sheet
#[derive(Debug, Clone, Copy)]
enum Direction {
North,
South,
East,
West,
}
const ALL_DIRECTIONS: [Direction; 4] = [
Direction::North,
Direction::South,
Direction::East,
Direction::West,
];
for dir in ALL_DIRECTIONS {
println!("{:?}", dir);
}
Quick rules
- Rust enums do not have a built-in
values()method. - To iterate variants, define a manual list or use a crate.
Copyis useful for small enums without data.- If variants contain data, full iteration may not make sense.
strumis a popular crate forEnumIter.
Handy pattern
impl Direction {
fn all() -> &'static [Direction] {
&[
Direction::North,
Direction::South,
Direction::East,
Direction::West,
]
}
}
With strum
FAQ
Is there a built-in values() function for Rust enums?
No. Rust does not automatically generate a values() method for enums.
What is the simplest way to iterate over enum variants in Rust?
Create a constant array containing all variants and loop over it.
Can I make Rust enums behave more like Java enums?
Yes. A common pattern is to add an all() method that returns a slice of all variants.
What crate is commonly used for enum iteration in Rust?
strum is a popular crate. It can derive iteration support with EnumIter.
Does enum iteration work for enums with data fields?
Not automatically in a general way. Variants with fields can represent many possible values.
Should I use a manual array or a crate?
Use a manual array for small, simple projects. Use a crate if you want less boilerplate or have many enums.
Why does Rust not provide this automatically?
Because Rust enums are more flexible than simple named constants, and Rust generally prefers explicit patterns over hidden runtime behavior.
Mini Project
Description
Build a small command-line helper that lists all possible movement directions and prints a short instruction for each one. This demonstrates how to define an enum, create a manual iterable list of variants, and process each variant in a loop.
Goal
Create a Rust program that iterates through every Direction variant and prints a human-readable message for each one.
Requirements
- Define a
Directionenum withNorth,South,East, andWest. - Create a reusable way to access all enum variants.
- Loop through every direction and print a message.
- Use
matchto generate a different message for each direction.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Convert an Integer to a String in Rust
Learn the current Rust way to convert integers to strings, why `to_str()` no longer works, and when to use `to_string()` or `format!`.