Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem calling a trait method of a struct in a vector

Tags:

rust

traits

What I want to do

The method in this case is Flower::update. I need to call update on a Flower in this case, in a loop. The loop is in Garden::update_all(), and this loop defines flower and then tries to call update on that flower but does not work.

What I have tried but why it hasen't work

I have looked at E0507, and other articles about similar problems. The ones that seem like the might help mention that I need to implement Copy on flowers, so the vector of Flowers, so Flower also needs to implement Copy but can't because the trait 'Copy' may not be implemented for this type.

Also, the problem is that I don't want to copy the data, I want to call a method on the reference. Like flower[0].update; or something similar. I don't need to use the data, only call a method that changes it.

What my best guess is

It has something to do with self and it's mutability and how I look through flowers and assign a single Flower to a variable flower and try to call a method on a created mutable reference. But I'm not sure. Should the method have &mut self or &self? Should the loop make a new mut flower, or just a normal flower, Should the loop be &self.flowers or self.flowers. I've tried many variation and I think it might be some combination of these, and an extra thing I don't know about.

pub trait FlowerTrait {
    fn update(&mut self);
}

pub struct Flower {
   pub number: i32,
}

impl FlowerTrait for Flower {
    fn update(&mut self) {
        self.number += 1;
    }
}

pub trait GardenTrait {
    fn update_all(&mut self);
}

pub struct Garden {
    pub flowers: Vec<Flower>,
}

impl GardenTrait for Garden {
    fn update_all(&mut self) {
        for mut flower in self.flowers {
            flower.update();
        }
    }
}

fn main() {
    let mut garden: Garden = Garden {
        flowers: Vec::<Flower>::new(),
    };

    garden.update_all();
}
like image 575
Dzjek R Avatar asked Dec 06 '25 20:12

Dzjek R


1 Answers

For a better post, you should have included the error message you get.

The problem occurs because a for loop behind the scenes uses the into_iterator method from the IntoIterator trait, and conversion is consuming, i.e., a move occurs.

The solution is to iterate over references instead. Simply change your for loop to

for flower in &mut self.flowers {
  // ...
}

Or alternatively

for flower in self.flowers.iter_mut() { 
  // ...
}

That creates an iterator over references (borrows) instead.

See here: rust playground

like image 129
Lagerbaer Avatar answered Dec 08 '25 22:12

Lagerbaer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!