0

I am trying to implement an algorithm like below. I don't know how to make the local variable long enough. May be my design is fully wrong.

trait Metric {
    fn on_add(&mut self, _i: i32);
}
trait Update {
    fn update(&mut self, _i: i32);
}

struct Metric1 {}
impl Metric for Metric1 {
    fn on_add(&mut self, _i: i32) {
        unimplemented!()
    }
}
impl Update for Metric1 {
    fn update(&mut self, _i: i32) {
        unimplemented!()
    }
}

struct Metric2 {}
impl Metric for Metric2 {
    fn on_add(&mut self, _i: i32) {
        unimplemented!()
    }
}
impl Update for Metric2 {
    fn update(&mut self, _i: i32) {
        unimplemented!()
    }
}

struct collector<'a> {
    metrics: Vec<&'a mut dyn Metric>,
}

fn main() {
    let mut vector_metrics: Vec<Box<dyn Metric>> = Vec::new();
    let mut vector_update: Vec<Box<dyn Update>> = Vec::new();
    for i in 0..2 {
        if i ==0{
        vector_metrics.push(Box::new(Metric1 {}));
        vector_update.push(Box::new(Metric1 {}));

        }
        else{
        vector_metrics.push(Box::new(Metric2 {}));
        vector_update.push(Box::new(Metric2 {}));
        }
    }
    let col_vector : Vec<& mut dyn Metric> = Vec::new();
    for met in vector_metrics{
        col_vector.push(&mut *met)
    }
    let coll = collector{metrics:col_vector};
}

Rust playground

FZs
  • 16,581
  • 13
  • 41
  • 50
Farbod PM
  • 122
  • 6

1 Answers1

1

vector_metrics owns the Metric objects it holds. And you are trying to create a new vector with a reference to those objects.

for met in vector_metrics moves each metric out of vector_metrics and into your met loop variable. Keeping a reference means there is no owner and the metric is dropped at the end of each loop iteration. To keep the metric owned you would need to store the owned value in col_vector:

    let mut col_vector : Vec<Box<dyn Metric>> = Vec::new();
    for met in vector_metrics{
        col_vector.push(met);
    }

Alternatively, you can iterate over vector_metrics non-destructively by taking a mutable reference to each element. This keeps ownership of the metrics in vector_metrics:

    let mut col_vector : Vec<& mut dyn Metric> = Vec::new();
    for met in &mut vector_metrics{
        col_vector.push(&mut **met);
    }
Jonathan Giddy
  • 1,435
  • 10
  • 6