Structs, Enums, and Modules
Explore struct and enum definitions for creating custom data structures. Learn how to organize code using modules.
Enums in Rust: Defining Custom Data Types
In Rust, enums (short for enumerations) are a powerful way to define a type that can be one of several possible variants. They allow you to create expressive and type-safe code by representing a fixed set of options.
What are Enums?
An enum defines a new type where each possible value is named a variant. Enums are useful when you have a variable that can only take on a limited number of known values. They are more descriptive and less error-prone than using integers or strings to represent these choices.
Defining Enums
Here's a basic example of an enum definition:
enum WebEvent {
PageLoad,
PageUnload,
KeyPress(char),
Paste(String),
Click { x: i64, y: i64 },
}
In this example, WebEvent
is an enum with five variants:
PageLoad
andPageUnload
are simple variants without any associated data.KeyPress
is a variant that holds a singlechar
value.Paste
is a variant that holds aString
.Click
is a variant that holds a struct-like definition with named fieldsx
andy
of typei64
.
Enums With and Without Data
As shown in the example above, enum variants can optionally hold data. This makes enums incredibly versatile. They can represent simple options or complex data structures.
Enums Without Data (Unit Variants)
Unit variants, like PageLoad
and PageUnload
, are similar to constants. They represent a specific state or option without any additional information.
enum Status {
Online,
Offline,
Idle,
}
Enums With Data
Variants can hold data of any type. This data can be a single value, a tuple of values, or even a struct-like definition with named fields.
enum Result<T, E> {
Ok(T),
Err(E),
}
The Result
enum (which is part of Rust's standard library) is a prime example. It represents the outcome of an operation that might succeed or fail. Ok
holds the successful result (of type T
), and Err
holds the error value (of type E
). This is a generic enum allowing it to return success and error types of different types.
Using Enums
To use an enum, you refer to its variants using the enum's name followed by the scope resolution operator (::
) and the variant name.
let load = WebEvent::PageLoad;
let key = WebEvent::KeyPress('x');
let paste = WebEvent::Paste("some text".to_string());
let click = WebEvent::Click { x: 10, y: 20 };
Pattern Matching with Enums
One of the most powerful features of enums is their integration with pattern matching using the match
keyword. Pattern matching allows you to execute different code blocks depending on which variant of the enum is present.
fn process_event(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("Page loaded!"),
WebEvent::PageUnload => println!("Page unloaded!"),
WebEvent::KeyPress(character) => println!("Key pressed: {}", character),
WebEvent::Paste(text) => println!("Pasted text: {}", text),
WebEvent::Click { x, y } => println!("Clicked at x={}, y={}", x, y),
}
}
fn main() {
let my_event = WebEvent::Click { x: 50, y: 100 };
process_event(my_event);
}
In this example, the process_event
function takes a WebEvent
as input. The match
statement checks which variant the event
is. For variants that hold data (KeyPress
, Paste
, Click
), you can bind the data to variables (e.g., character
, text
, x
, y
) and use them in the corresponding code block.
The match
expression must be exhaustive, meaning it must handle all possible variants of the enum. If you don't want to handle all variants explicitly, you can use the underscore (_
) as a catch-all pattern.
match some_result {
Ok(value) => println!("Success: {}", value),
Err(_) => println!("An error occurred!"), // Ignoring the specific error
}
Conclusion
Enums are a fundamental part of Rust programming. They provide a way to create type-safe and expressive code by defining custom data types that can hold one of several possible values. The combination of enums and pattern matching allows you to write elegant and robust code that handles different scenarios effectively. Use enums whenever you have a variable that can only take on a limited number of known values.