Instances of generic structure, different generics, not known at compile time

Hi,
I am trying to store multiple variants of generic structures. And i am also in need of updating and reading from these. How many instances or what type each structure is using, is not know at compile time.

Here is my simplified structure, and some code which is not working. Just to illustrate what I am trying to achieve.

Example 1:

use std::any::Any;

struct Metric<T> {
    val: T,
}
fn main(){
    // Create instances of Metric<i32> and Metric<String>
    let mut metric_i32 = Metric { val: 42 };
    let mut metric_string = Metric { val: "Hello".to_string() };

    let vec_of_unknown_metrics = vec![metric_i32,metric_string];
    
    vec_of_unknown_metrics[0].set_value(42);
    vec_of_unknown_metrics[1].set_value("dfsfd");
}

Example 2:

use std::any::Any;
trait MetricOperations {
    // fn get_value(&self) -> &dyn std::fmt::Display;
    fn set_value<'a>(&mut self, new_value: Box<dyn Any + 'a>);
}
struct Metric<T> {
    val: T,
}
impl<T: Clone> MetricOperations for Metric<T> {
    fn set_value<'a>(&mut self, new_value: Box<dyn Any + 'a>) 
        where T: 'a
    {
        if let Some(new_val) = new_value.downcast_ref::<T>() {
            self.val = new_val.clone();
        } else {
            panic!("Type mismatch");
        }
    }
}

fn main(){
    let mut metric_i32 = Metric { val: 42 };
    let mut metric_string = Metric { val: "Hello".to_string() };
    
    let mut vec_of_unknown_metrics: Vec<Box<dyn MetricOperations>> = Vec::new();

    vec_of_unknown_metrics.push(Box::new(metric_i32));
    vec_of_unknown_metrics.push(Box::new(metric_string));

    vec_of_unknown_metrics[0].set_value(Box::new(32));
    vec_of_unknown_metrics[1].set_value(Box::new(String::from("fdsf")));
    
}

}

The data is going to be populated via an API or CSV at runtime, and the source data has a field for datatype which will be used to create the proper type in my program)

I have tinkered with Vec, Box, Cons, deref, and I am currently spinning in circles here.. Any ideas anyone?

In your second example, do you need to support for a type T: 'a, or would T: 'static suffice? If you only need to support owned data types like integers and strings, you could simplify the example by replacing 'a with 'static and make it compile that way.

If you need to have 'a around, this compiles as well.

1 Like

Thank you so much!

1 Like