Generic enum with 2 variables

is it possible to create a generic enum

enum Value<T,U>
{
Integer(T),
Float(U)
}

and match them to print it's value

Yes.

use std::fmt::Display;

enum Value<T, U> {
    Integer(T),
    Float(U),
}

fn print_value<T, U>(v: Value<T, U>)
where
    T: Display,
    U: Display,
{
    match v {
        Value::Integer(i) => println!("{}", i),
        Value::Float(f) => println!("{}", f),
    }
}

Note that if you want to print values of a generic type, you need to specify that the type must implement Display (or Debug, if you're doing println!("{:?}", i) or similar).

You could also apply the constraint to the type itself, if you want to ensure that all instances of a Value can be printed:

enum Value<T, U>
where
    T: Display,
    U: Display,
{
    Integer(T),
    Float(U),
}
2 Likes

how to initialize value for integer and float in main function an then pass it as parameter to print_value function
some thing ike this
use std::fmt::Display;
enum Value<T, U> {
Integer(T),
Float(U),
}
fn main()
{
let parameter = Value::Float(600.03);
print_value(parameter);

}

fn print_value<T:Display, U:Display>(v: Value<T, U>)
{
match v {
Value::Integer(i) => println!("{}", i),
Value::Float(f) => println!("{}", f),
}
}
but showing error:

8 | let parameter = Value::Float(600.03);
| --------- ^^^^^^^^^^^^ cannot infer type for T
| |
| consider giving parameter the explicit type Value<T, f64>, where the type parameter T is specified

The issue here is that the compiler cannot tell what type you intend parameter to be - it can guess from Value::Float(600.03) that the type of U must be f32, but that's only one of the two type parameters defined on Value.

To resolve this, you'll need to give parameter a type annotation:

let parameter: Value<i32, f32> = Value::Float(600.03);

Note that even though parameter does not contain a Value::Integer, the compiler still needs to know the type that it would contain if it did - the size of a enum in memory is detemined by the largest of all the types it could contain.


To take a step back for a second - does it make sense for this type to be generic? You have variants called Integer and Float, but there's nothing stopping you from doing something like Value::Integer("a string"). The following type definition might make more sense:

enum Value {
    Integer(i32),
    Float(f32),
}
3 Likes