12

I'm having a hard time with the borrow checker.

for item in self.xxx.iter() {
    self.modify_self_but_not_xxx(item);
}

The above code worked before I refactored some code into modify_self_but_not_xxx():

error: cannot borrow `*self` as mutable because `self.xxx` is also borrowed as immutable

How can I call a mutating method while holding a reference to self (e.g. from within a for-loop)?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366

1 Answers1

13

How can I call a mutating method while holding a reference to self (e.g. from within a for-loop)?

You can't, that's exactly what the borrowing rules prevent.

The main idea is that in your code, the borrow checker cannot possibly know that self.modify_self_but_not_xxx(..) will not modify xxx.

However, you can mutate self.yyy or any other parameters, so either you can:

  • do the computations of modify_self_but_not_xxx(..) directly in your loop body
  • define a helper function taking mutable references to update them:

    fn do_computations(item: Foo, a: &mut Bar, b: &mut Baz) { /* ... */ }
    
    /* ... */
    
    for item in self.xxx.iter() {
        do_computations(item, &mut self.bar, &mut self.baz);
    }
    
  • define a helper struct that has helper methods
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Levans
  • 14,196
  • 3
  • 49
  • 53
  • Thanks, I understand now. **Lesson learned:** when designing functions avoid references to `self` if possible -- don't borrow more than what is minimally necessary. – MarkOfDarkness Dec 08 '14 at 07:56
  • There is distinction between method and function in Rust. [The Book ch](https://doc.rust-lang.org/book/ch05-03-method-syntax.html). In short method has reference to Self, while function is simply associated with a struct. – dobhareach Apr 06 '23 at 07:49