Should a reference to an enum be dereferenced before it is matched?

Solution 1:

You can't move out of an immutable reference, so you don't have to worry about that being the case.

It's worth considering that one would expect matches to work somewhat akin to (Partial)Eq, and that takes &self. In other words, one would expect it to take a reference implicitly unless forced. This is easily confirmed with a little experimentation.

It's worth noting that *self is not a move - it's a reference to a memory location. It is thus an lvalue. Ergo,

When the head expression is an lvalue, the match does not allocate a temporary location (however, a by-value binding may copy or move from the lvalue).

https://doc.rust-lang.org/stable/reference/expressions/match-expr.html

If a temporary location is not allocated, a move cannot occur. Thus the behaviour is guaranteed. As the parenthetical notes, internal data can still get moved out from destructuring pattern, which would cause a problem. This, however, is true regardless of whether you are matching on self or *self.

Using *self seems to be an informal idiom, and should be preferred.

Solution 2:

As of Rust 1.26, the idiomatic solution is neither; you don't have to dereference the value or add & to the patterns:

fn contains_blue(&self) -> bool {
    match self {
        Color::Blue => true,
        Color::Teal => true,
        Color::Purple => true,
        _ => false,
    }
}

This is thanks to improved match ergonomics.

You can also use pattern alternation in this case:

match self {
    Color::Blue | Color::Teal | Color::Purple => true,
    _ => false,
}

Solution 3:

I personally prefer the second. It conveys the intent better, in my opinion.