Lets say I have an enum E
, that might be auto-generated or outside of my control, with many variants and each variant having a number of fields.
enum E {
A {
x1: u8,
x2: u8,
x3: u8,
// ...
x9: u8,
},
B,
}
In reality the fields might be longer and neither nice to remember, nor nice to type.
I now want to write functions that operate on (variants of) E
. However, I am also lazy, and I don't want to repeat myself, declaring each used field explicitly when destructuring the enum*.
Intuitively I would have expected the binding operator @
to do the job here, but it only binds the whole enum e
, not the given variant E::A
.
What is the shortest / most elegant way to achieve the following intention?
fn f(e: &E) {
match e {
bad @ E::A { .. } => dbg!(bad.x1),
_ => {}
}
}
*Update since this has been brought up in two answers already, I do not want to match with E::A { x1, .. }
, as this gets tedious when needing multiple fields with long names. In the example below, I would have to type out some_other_field_with_an_impossibly_long_name
twice in my own code (once when binding it, once when using it), whereas in the hypothetical bad @ E::A
case I'd have to type it out only once.
match e {
E::A { some_field_with_a_long_name, some_other_field_with_an_impossibly_long_name, yet_another_field, .. } => dbg!(some_other_field_with_an_impossibly_long_name),
_ => {}
}
I think the following could help:
fn f(e: &E) {
match e {
E::A {x1, .. } => {dbg!(x1);},
_ => {}
};
}
E::A {x1,..}
is short for bad @ E::A {x1:x1, ..}
and binds the value of bad.x1
to a new local variable x1
that is available in the body scope.
You may use a macro with variadic args, so the compiler does the typing long names twice, and it binds as many as parameters you need. You may call your function inside the macro instead of println:
f!(&e, x1);
f!(&e, x2, x1);
macro_rules! f {
($e: expr, $( $name:ident ),+ ) => {
match $e {
E::A { $($name),* , ..} => {
println!("{:?}", &[$($name),*]); // call your function here.
}
_ => {}
}
};
}
Try it on the Rust Playground
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With