I have a match statement that returns a Box<dyn MyTrait>
based on an enum. I'm able to assign the result to a typed variable and use it as intended. However, I would prefer stylistically to return the match result directly. It's a minor nit, but when chaining map()
calls and such, it looks a little silly to have it as written here:
struct StructA;
struct StructB;
trait MyTrait {
fn is_a(&self) -> bool;
}
impl MyTrait for StructA {
fn is_a(&self) -> bool {
true
}
}
impl MyTrait for StructB {
fn is_a(&self) -> bool {
false
}
}
enum MyEnum {
A,
B,
}
fn main() {
let values: [MyEnum; 2] = [
MyEnum::A,
MyEnum::B
];
values
.iter()
.map(|e| {
// I would like to "cast" (sorry, that's the C programmer in me
// speaking) the match statement's return value as Box<dyn MyTrait>
// directly without the use of the b variable.
let b: Box<dyn MyTrait> = match e {
MyEnum::A => Box::new(StructA),
MyEnum::B => Box::new(StructB),
};
b
})
.for_each(|b| println!("{}", b.is_a()))
}
If I change the map call to the following, it fails to compile because the arms have different return types:
values
.iter()
// Could I maybe use something like the "as" keyword here to "cast" the
// result?
.map(|e| match e {
MyEnum::A => Box::new(StructA),
MyEnum::B => Box::new(StructB),
})
.for_each(|b| println!("{}", b.is_a()))
Compiling playground v0.0.1 (/playground)
error[E0308]: `match` arms have incompatible types
--> src/main.rs:35:26
|
33 | .map(|e| match e {
| __________________-
34 | | MyEnum::A => Box::new(StructA),
| | ----------------- this is found to be of type `Box<StructA>`
35 | | MyEnum::B => Box::new(StructB),
| | ^^^^^^^^^^^^^^^^^ expected `Box<StructA>`, found `Box<StructB>`
36 | | })
| |_________- `match` arms have incompatible types
|
= note: expected struct `Box<StructA>`
found struct `Box<StructB>`
For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error
An idea I had was to implement something like the From
trait to do the conversion myself, but this use case seems simple enough that I shouldn't need to do something like that, given that the typed variable just works. Is there a simpler way to specify the return type in the match statement?