Why match on enum variant with option get a reference

Hello,

I'm a newbie in Rust and I cannot understand why the following code requires the option needs to be deferenced when it isn't declared as a reference.

#[derive(Debug)]
enum Amount {
    One,
    Few(Option<i64>),
}

impl Amount {
    fn how_much(&self) -> Option<i64> {
        match self {
            Amount::One => Some(1),
            Amount::Few(a) => a,
        }
    }
}

fn main() {
    let amount = Amount::One;
    println!("{:?}", amount.how_much());

    let amount = Amount::Few(Some(5));
    println!("{:?}", amount.how_much());

    let amount = Amount::Few(None);
    println!("{:?}", amount.how_much());
}

This doesn't compile with the error:

9  | /         match self {
10 | |             Amount::One => Some(1),
   | |                            ------- this is found to be of type `std::option::Option<i64>`
11 | |             Amount::Few(a) => a,
   | |                               ^
   | |                               |
   | |                               expected enum `std::option::Option`, found reference
   | |                               help: consider dereferencing the borrow: `*a`
12 | |         }
   | |_________- `match` arms have incompatible types

Link to the playground: Rust Playground

I know how to solve it, it's about referencing the *a on line 11, however, I don't understand why a is a reference when the enum variant Few is declared with Option<i64> and not &Option<i64>.

Thank you in advance for your help.

This is because self has the type &Amount, and when you match on a reference, the pattern gives you references to fields.

4 Likes