Rust Enums and match

Model alternatives with an enum and handle each one with match.

Rust
enum Shape {
    Circle(u32),
    Square(u32),
}

fn area(shape: &Shape) -> u32 {
    match shape {
        Shape::Circle(r) => 3 * r * r,
        Shape::Square(s) => s * s,
    }
}

fn main() {
    println!("{}", area(&Shape::Circle(2)));
    println!("{}", area(&Shape::Square(5)));
}
Output
12
25

Explanation

A Rust enum lists the forms a value can take, and each form can carry data. Shape::Circle(u32) holds a radius and Shape::Square(u32) holds a side length.

match inspects the form and runs the matching arm. The compiler requires the arms to cover every variant, so adding a new variant later turns every incomplete match into a compile error. The area function borrows the shape with &, so the caller keeps ownership. Circle area uses 3 as a whole-number stand-in for pi to stay in integers.

Explore the dry run
Guided walkthroughReady
1enum Shape {
2 Circle(u32),
3 Square(u32),
4}
5
6fn area(shape: &Shape) -> u32 {
7 match shape {
8 Shape::Circle(r) => 3 * r * r,
9 Shape::Square(s) => s * s,
10 }
11}
12
13fn main() {
14 println!("{}", area(&Shape::Circle(2)));
15 println!("{}", area(&Shape::Square(5)));
16}

Follow the example

Start to inspect the source, values, and output. These prepared steps explain the published sample; grouped loop steps describe multiple iterations.

View the complete dry-run table
Prepared trace of the published program. Some rows group repeated iterations.
Step / lineWhat happensState after stepOutput so far
Two variants, each holding one number.—
—
For a circle of radius 2 the arm computes 3 * 2 * 2.r = 2
—
The circle arm returns 12.return = 12
12
The square arm returns 5 * 5.return = 25
12
25

Cost and common mistakes

O(1) time and space.

  • Leaving out a variant in match is a compile error unless you add a catch-all arm _.
  • Integer overflow in u32 arithmetic panics in debug builds, so keep sizes small.

Try it yourself

Add a Rectangle(u32, u32) variant.

Reveal answer and reasoning

Add Rectangle(u32, u32) to the enum and the arm Shape::Rectangle(w, h) => w * h, otherwise match will not compile.

Further reading