Introduction
An enum (enumeration) defines a type by listing its possible variants. Unlike C-style enums, which are just a set of named integer constants, Rust enums are far more powerful: each variant can hold its own data of different types and amounts. This makes enums ideal for modeling values that can be one of several distinct, well-defined shapes, such as an IP address that is either IPv4 or IPv6.
Cricket analogy: Rust's enum is like classifying a dismissal type — bowled, caught, or run out — where a C-style enum would just be a numbered scoreboard code, but Rust's caught variant can also carry who the fielder was.
Syntax
enum IpAddr {
V4(String),
V6(String),
}
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));Explanation
Each variant of IpAddr is a constructor for the enum type, and here both V4 and V6 hold a String. Variants aren't required to hold the same type or amount of data — one variant could hold a struct-like set of named fields, another could hold nothing at all. Enums pair naturally with the match expression, which forces you to handle every variant, making illegal states easier to avoid. Two of the most important enums in the standard library, Option<T> and Result<T, E>, are themselves ordinary enums (Option has Some(T) and None; Result has Ok(T) and Err(E)) — they are covered in depth in their own topics.
Cricket analogy: IpAddr::V4(String) is like a wicket-type constructor — Bowled(batsman_name) — each variant builds a specific kind of value; match then forces you to handle stumped, caught, and run-out cases, so none is missed.
Example
enum IpAddr {
V4(String),
V6(String),
}
fn describe(addr: &IpAddr) -> String {
match addr {
IpAddr::V4(s) => format!("IPv4 address: {}", s),
IpAddr::V6(s) => format!("IPv6 address: {}", s),
}
}
fn main() {
let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));
println!("{}", describe(&home));
println!("{}", describe(&loopback));
}
// Output:
// IPv4 address: 127.0.0.1
// IPv6 address: ::1Key Takeaways
- Enums list the possible variants a value of that type can take.
- Unlike C-style enums, Rust variants can each hold different types and amounts of data.
- Enum variants are constructed with the
Enum::Variant(...)syntax. matchis the idiomatic way to handle enums and ensures every variant is covered.Option<T>andResult<T, E>are standard library enums built on this same mechanism.
Practice what you learned
1. How does a Rust enum differ from a C-style enum?
2. How do you construct a value of the `V4` variant of `enum IpAddr { V4(String), V6(String) }`?
3. Which standard library type is itself defined as an enum with `Some(T)` and `None` variants?
4. What construct is most commonly used to handle all variants of an enum?
5. Which enum represents an operation that can succeed or fail?
Was this page helpful?
You May Also Like
Structs in Rust
Structs let you group related values into a single named type with fields you access by name.
match Expressions in Rust
Master Rust's exhaustive match expression for pattern matching on values, enums, tuples, and ranges.
The Option Type in Rust
Understand how Rust's Option<T> enum replaces null to represent optional values safely.
Error Handling in Rust (Result)
Learn how Rust models recoverable errors with the Result enum and the ? operator instead of exceptions.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics