2

I have a generic enum:

enum Holder<T> {
    None,
    One(T),
    Two(T, T),
}

and I have placed two strings in it:

let two_strings = Holder::Two(String::from("abc"), String::from("abc"));

I want to write a function which takes the enum, checks if it is of type String and prints it:

fn print_name_from_enum<T>(hold: T) {
    match hold {
        Holder::Two(a, b) => println!("Your Name is {} {}", a, b),
    }
}

The compiler complains because I do not specify the type of holder:

error[E0308]: mismatched types
  --> src/lib.rs:10:9
   |
10 |         Holder::Two(a, b) => println!("Your Name is {} {}", a, b),
   |         ^^^^^^^^^^^^^^^^^ expected type parameter, found enum `Holder`
   |
   = note: expected type `T`
              found type `Holder<_>`

but if I give the type:

match hold {
    Holder<String>::Two(a, b) => {
        println!("Your Name is {} {}", a, b)
    }
}

the compiler complains as well:

error: expected one of `=>`, `@`, `if`, or `|`, found `<`
  --> src/lib.rs:10:15
   |
10 |         Holder<String>::Two(a, b) => {
   |               ^ expected one of `=>`, `@`, `if`, or `|` here

How do I solve this issue? What am I doing wrong here?

Solution

Thanks to @mcarton I found the mistake. The way it should be is

fn print_name_from_enum<T: ToString>(hold: Holder<T>) {
    match hold {
        Holder::Two(a, b) => {
            println!("Your Name is {first} {second}", first = a.to_string(), 
                                                        second = b.to_string())
        }
        _ => {
            println!("ooPPs.")
        }
    }
}

I need to add the enum type as an argument, and for T it has to be add that its function to_string() is implemented.

Benji Z.
  • 63
  • 5
  • 1
    `fn print_name_from_enum(hold: T)`, this does not say `print_name_from_enum` takes a parameter of type `Holder`, but rather any type with no constraint at all. Did you mean `print_name_from_enum(hold: Holder)`? – mcarton Oct 04 '18 at 20:02
  • 2
    _"a function which takes the enum, checks if it is of string type and prints it"_ — This isn't possible. For the function to take the enum, it must be known at compile-time what the parameter `T` is. So a function can't really "test" that - if it needs it to be a string then it will either compile or won't compile. – Peter Hall Oct 04 '18 at 20:05
  • [The duplicates applied to your question](https://play.rust-lang.org/?gist=53996aa7d42c97f6289e06935239b41f&version=stable&mode=debug&edition=2015). – Shepmaster Oct 04 '18 at 20:47

0 Answers0