Enums with Data
Attach values to variants.
Enums with Data is a free Learn Rust Coding lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Learn Rust Coding learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Variants Can Hold Data
So far our variants were just names. In Rust, a variant can also carry data inside parentheses.
This lets a single enum describe both the kind of value and the value itself.
enum Message {
Quit,
Move(i32, i32),
Write(String),
}A Variant with One Value
Put a type in parentheses to attach one piece of data to a variant.
Here Celsius(f64) means the Celsius variant holds a f64 number. You supply that number when you build the value.
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(21.5);
println!("Created a temperature");
}Variants with Several Values
A variant can hold multiple values, separated by commas.
Move(i32, i32) stores two integers, perhaps an x and a y coordinate. You pass both when creating it.
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let r = Shape::Rectangle(3.0, 4.0);
println!("Made a rectangle");
}Extracting Data with match
To read the data inside a variant, name it in the pattern. The names become variables you can use in that arm.
Here Shape::Circle(r) binds the stored radius to r.
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Circle(2.0);
match s {
Shape::Circle(r) => println!("radius {}", r),
Shape::Rectangle(w, h) => println!("{} x {}", w, h),
}
}Using the Bound Values
Once data is bound to a name, you can compute with it like any variable.
This program matches a shape and calculates its area, returning the result from match.
enum Shape {
Circle(f64),
Rectangle(f64, f64),
}
fn main() {
let s = Shape::Rectangle(3.0, 4.0);
let area = match s {
Shape::Circle(r) => 3.14 * r * r,
Shape::Rectangle(w, h) => w * h,
};
println!("area = {}", area);
}Different Data per Variant
Each variant can hold a different shape of data, and some can hold none at all.
This flexibility is what makes enums so expressive: one type models many distinct cases.
enum Message {
Quit,
Move(i32, i32),
Write(String),
}Struct-Like Variants
A variant can use named fields with curly braces, just like a struct. This makes the meaning of each field clear.
You build it by naming each field, and match it the same way.
enum Event {
Click { x: i32, y: i32 },
KeyPress(char),
}
fn main() {
let e = Event::Click { x: 10, y: 20 };
match e {
Event::Click { x, y } => println!("click at {},{}", x, y),
Event::KeyPress(c) => println!("key {}", c),
}
}Strings in Variants
Variants can hold owned data like a String. Matching gives you access to the text.
Note: matching by value moves the data out, which is fine here because we use it right away.
enum Message {
Write(String),
Quit,
}
fn main() {
let m = Message::Write(String::from("hello"));
match m {
Message::Write(text) => println!("text: {}", text),
Message::Quit => println!("bye"),
}
}The Standard Option Enum
Rust's built-in Option<T> is an enum with data: Some(T) holds a value and None holds nothing.
It is how Rust represents "maybe a value" without using null. You match it just like your own enums.
fn main() {
let maybe: Option<i32> = Some(5);
match maybe {
Some(n) => println!("got {}", n),
None => println!("nothing"),
}
}Putting It Together
This complete program models temperatures, then converts a Celsius reading to Fahrenheit inside a match.
Try changing the variant or its value and re-running.
enum Temperature {
Celsius(f64),
Fahrenheit(f64),
}
fn main() {
let t = Temperature::Celsius(25.0);
let f = match t {
Temperature::Celsius(c) => c * 9.0 / 5.0 + 32.0,
Temperature::Fahrenheit(f) => f,
};
println!("{} F", f);
}When to Use Data Variants
Reach for data-carrying variants when each case naturally comes with extra information.
- A
Circleneeds a radius. - A
Writemessage needs its text. - A
Moveneeds coordinates.
Bundling the data with the variant keeps related information together and type-safe.
Quick Check
Check your understanding of enums that carry data.
Recap
You learned that enum variants can carry data: a single value, several values, named struct-like fields, or none at all.
You read that data by naming it in a match pattern, like Circle(r). The standard Option type works the same way. Next you will refine matches with guards and bindings.
Frequently asked questions
Is the “Enums with Data” lesson free?
Yes — the full text of “Enums with Data” is free to read here on the web, and the Learn Rust Coding course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Learn Rust Coding course, upgrade to CoddyKit PRO.
What will I learn in “Enums with Data”?
Attach values to variants. You practise Learn Rust Coding with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Learn Rust Coding?
No prior experience is required. Learn Rust Coding on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Enums with Data” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Learn Rust Coding lesson?
Yes. Every Learn Rust Coding lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.