I have a struct that has a vector of another struct type.
struct Element {
val: String,
}
struct Collection {
elements: Vec<Element>,
}
impl Collection {
fn process(&mut self) {
for entry in &self.elements.iter_mut() {
entry.val = "New value".to_string();
println!("{}", entry.val);
}
}
}
fn main() {
let e1 = Element {
val: "My first entry".to_string(),
};
let e2 = Element {
val: "My second entry".to_string(),
};
let mut c = Collection { elements: vec![] };
c.elements.push(e1);
c.elements.push(e2);
c.process();
}
When I try to iterate over it, I get the following error:
error[E0277]: the trait bound `&std::slice::IterMut<'_, Element>: std::iter::Iterator` is not satisfied
--> src/main.rs:11:22
|
11 | for entry in &self.elements.iter_mut() {
| -^^^^^^^^^^^^^^^^^^^^^^^^
| |
| `&std::slice::IterMut<'_, Element>` is not an iterator; maybe try calling `.iter()` or a similar method
| help: consider removing 1 leading `&`-references
|
= help: the trait `std::iter::Iterator` is not implemented for `&std::slice::IterMut<'_, Element>`
= note: required by `std::iter::IntoIterator::into_iter`
I think this is because &self.elements
is really a reference. Using self.elements
would work, but I was hoping to modify the actual objects rather than a copy.
What would be a proper way of doing this?
Switch to this:
for entry in self.elements.iter_mut() { /* ... */ }
Or more idiomatically:
for entry in &mut self.elements { /* ... */ }
IterMut
contains a reference to the items in the vector (and thus will change the vector items directly), but it is itself an object on the stack that will be changed as the iteration progresses.
the trait bound `&std::slice::IterMut<'_, Element>: std::iter::Iterator` is not satisfied
This is saying that you've got an IterMut
by reference. That is, the precedence is different from what you think it is:
&self.elements.iter_mut()
&(self.elements.iter_mut()) // Is this
(&self.elements).iter_mut() // Not this
However, we'd have to do something like this:
(&mut self.elements).iter_mut()
because iter_mut
needs a mutable reference as the receiver. Rust understands that and lets us just do the straightforward version and appropriately pass the mutability around:
self.elements.iter_mut()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With