Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

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
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
843 views
Welcome To Ask or Share your Answers For Others

1 Answer

I'd create a map method on your enum:

#[derive(Debug)]
enum MyEnum<T> {
    B,
    C,
    D(T),
}

impl<T> MyEnum<T> {
    fn map<U>(self, f: impl FnOnce(T) -> U) -> MyEnum<U> {
        use MyEnum::*;

        match self {
            B => B,
            C => C,
            D(x) => D(f(x)),
        }
    }
}

fn main() {
    let answer = MyEnum::D(42);
    let answer2 = answer.map(|x| x.to_string());
    println!("{:?}", answer2);
}

This is similar to existing map methods, such as Option::map.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...