r/rust•
DataPath

match branch destructuring of only certain members?

Suppose I have an enum of structs:

enum Money {
    Penny  { value_in_hundredths: u32, in_circulation: u64 },
    One    { value: u32, in_circulation: u64 },
}

If I wanted to use only its "in_circulation" member in a match, I might do this:

let curr = [
    Money::Penny  { value_in_hundredths:  1, in_circulation: 1650000000000 },
    Money::One    { value:   1,              in_circulation:    9500000000 },
];
let mut total_circulation: u64 = 0;
for unit in curr.iter() {
    total_circulation += match unit {
        &Money::Penny  { _, in_circulation } => in_circulation,
        &Money::One    { _, in_circulation } => in_circulation,
    };
}
println!("Total currency in circulation: {}", total_circulation);

Unfortunately, that leads to lots of not found in this scope and missing field 'value_in_hundredths' and missing field 'in_circulation' type errors.

If I replace all the "_" with the appropriate value or value_in_hundredths field, then I get a warning about an unused variable: 'value' or value_in_hundredths.

What's the right way to elide the first member of the struct inside the match?

Posted Sep 13, 2017, 10:51 PM UTC

63
_Timidger_way-cooler•

On a match where you only need to use part of the pattern you can do this:

match unit {
    &Money::Penny { in_circulation, .. } => in_circulation,
    &Money::One { in_circulation, .. } => in_circulation
}

In fact you can reduce it even further:

match unit {
    &Money::Penny { in_circulation, .. } | 
    &Money::One { in_circulation, .. } => in_circulation
}
6
DataPathOP•

That works! Perfect!

I had stumbled onto the { .. } syntax for eliding all members, but I didn't know that 1) you can reorder the members, and 2) you can use it as the last list item to elide all omitted members.

4
ErichDonGubler•

Since the field names are the same, it also looks really straightforward to use a pipe to combine the patterns on the left-hand side and just return the common field between them.

1
ErichDonGubler•

Since the field names are the same, it also looks really straightforward to use a pipe to combine the patterns on the left-hand side and just return the common field between them.

1