Structs and Enums

Model your domain so illegal states refuse to compile.

A struct groups related fields into one type; an enum says a value is exactly one of several shapes. match then makes you handle every case, so forgetting a variant is a compile error, not a surprise in production. Together they are how you model a domain in Rust.

And here is what “makes you handle every case” looks like when you do not. One missing variant, and the compiler lists exactly what the match forgot.

what the compiler says
enum Shape {
    Circle(f64),
    Rect(f64, f64),
}

fn area(s: &Shape) -> f64 {
    match s {
        Shape::Circle(r) => 3.14159 * r * r,
        // Rect is not handled; the compiler will name exactly what is missing
    }
}

fn main() {
    println!("{}", area(&Shape::Circle(1.0)));
}
error[E0004]: non-exhaustive patterns: `&Shape::Rect(_, _)` not covered
  --> main.rs:8:11
   |
 8 |     match s {
   |           ^ pattern `&Shape::Rect(_, _)` not covered
   |
note: `Shape` defined here
  --> main.rs:2:6
   |
 2 | enum Shape {
   |      ^^^^^
 3 |     Circle(f64),
 4 |     Rect(f64, f64),
   |     ---- not covered
   = note: the matched value is of type `&Shape`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
   |
 9 ~         Shape::Circle(r) => 3.14159 * r * r,
10 ~         &Shape::Rect(_, _) => todo!(),
   |

error: aborting due to 1 previous error

For more information about this error, try `rustc --explain E0004`.
check your understanding

An enum is declared as `enum Shape { Circle(f64), Rect(Point, Point) }`. What is the `f64` inside `Circle`?

You add a new variant to an enum that is matched in five places. What happens on the next build?

ask the tutor about this
learners marked this complete