Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mutable borrow in loop [duplicate]

I am trying to get a mutable borrow inside a loop, and I cannot get it to work. I've tried all the possible guards, raw pointers, everything.

struct Test<'a> {
    a: &'a str,
}

impl<'a> Test<'a> {
    pub fn new() -> Self {
        Test { a: &mut "test" }
    }

    pub fn dostuff(&'a mut self) {
        self.a = "test";
    }

    pub fn fixme(&'a mut self) {
        let mut i = 0;
        while i < 10 {
            self.dostuff();
            i += 1;
        }
    }
}

fn main() {
    let mut test = Test::new();
    test.fixme();
}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/main.rs:19:13
   |
19 |             self.dostuff();
   |             ^^^^ mutable borrow starts here in previous iteration of loop
...
22 |     }
   |     - mutable borrow ends here

Rust Playground example code

I cannot manage to figure how to solve this. I need the fix to still keep the function signatures the same. My code is a lot more complex, but this snippet strips it down to the bare minimum.

Here is the complete code of what I'm trying to solve.

like image 603
Chronium Avatar asked Sep 24 '17 19:09

Chronium


1 Answers

When you write fn dostuff(&'a mut self) you are enforcing that the reference to self must live at least as long as the lifetime 'a. But it's the same 'a as you have used in the definition of the Test struct. This means that callers of dostuff have to lend self for the entire lifetime of test. After dostuff() has been called once, self is now borrowed and the borrow doesn't finish until test is dropped. By definition, you can only call that function once, so you cannot call it in a loop.

I need the fix to still keep the function signatures the same

So, you should now understand that this is an impossible requirement. You can have either the function signature as it is, or you can call it in a loop. You can't have both.

like image 199
Peter Hall Avatar answered Nov 07 '22 17:11

Peter Hall