If I have a type like MyEnum<T>
, how can I map it in cases where not every variant is parameterized?
For example, I'd like to convert from MyEnum<u32>
to MyEnum<String>
:
enum MyEnum<T> {
B,
C,
D(T),
}
fn trans(a: MyEnum<u32>) -> MyEnum<String> {
match a {
MyEnum::D(i) => MyEnum::D(i.to_string()),
other_cases => other_cases,
}
}
fn main() {}
This fails with:
error[E0308]: match arms have incompatible types
--> src/main.rs:8:9
|
8 | match a {
| ^ expected struct `std::string::String`, found u32
|
= note: expected type `MyEnum<std::string::String>`
= note: found type `MyEnum<u32>`
note: match arm with an incompatible type
--> src/main.rs:10:28
|
10 | other_cases => other_cases,
| ^^^^^^^^^^^
Instead of the other_cases => other_cases
line, I tried this, also without success:
other_cases => {
let o: MyEnum<String> = other_cases;
o
}
I'd create a
map
method on your enum:This is similar to existing
map
methods, such asOption::map
.Some languages (like C++), use Duck Typing: if it quacks like a duck, it must be a duck, and therefore names matter. Rust does not.
In Rust, names are just some display utility for us mere humans, the
B
inMyEnum<u32>
andMyEnum<String>
may happen to have the same visual representation, but they are completely different syntactic entities as far as the language is concerned.There are multiple ways to alleviate your pain, though:
build.rs
script can be used as wellI'll show-case the latter:
Obviously, the latter makes it much easier to manually map things.
Well, this is actually an answer:
But repeating all variants isn't acceptable when there's a lot of them..