0

I have a vector of elements which I traverse and check for some property (immutable). In some cases I would then perform a mutable operation on a single item in that vector followed by an update of the container. How would I do that?

struct A {
    buffer: Vec<B>,
}

impl A {
    fn update(&self) {}
}

struct B {}

impl B {
    fn check(&self) -> bool { true }
    fn do_stuff(&mut self) {}
}

fn main() {
    let mut a = A { buffer: vec![B{}] };

    for b in a.buffer.iter_mut() { // mutable borrow occurs here
        if b.check() {
            b.do_stuff();
            a.update();  // imutable borrow occurs here
        }
    }
}

Alternatively, if I go for an immutable iter(). Is there a possibility to turn it mutable for the scope of do_stuff?

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
magu_
  • 4,766
  • 3
  • 45
  • 79

1 Answers1

0

Be aware that depending on your usecase, the compiler might actually prevent you from having a bug. Whether this is a case of 'the borrow checker getting in the way' or 'the borrow checker saving you from a bug' very much depends on what you actually are planning to do in the update method.

With its current signature this method is allowed to perform any number of operations on the Vec which might trigger its reallocation. Or even exchange the entire Vec for a different one. Both would be sure to invalidate your iterator over the buffer.

It's applaudable, that you try to refrain from using indices. In case you have a logic error here all you would do is to trade a compile time error for a runtime error (maybe an out of bound access), which is arguably harder to find or debug.

trent
  • 25,033
  • 7
  • 51
  • 90
Markus Klein
  • 1,202
  • 12
  • 10