This is my second day with Rust so please bear with me.
I'm not sure why I get a "cannot borrow" here:
struct A<'a> {
b: &'a mut B,
v: Vec<&'a B>,
}
struct B {
}
impl<'a> A<'a> {
fn x(&'a mut self) {
self.v.push(self.b);
}
}
fn main() {
let mut b = B { };
let b = &mut b;
let mut a = A {
b,
v: vec![],
};
a.x();
a.x();
}
The error I get:
error[E0499]: cannot borrow `a` as mutable more than once at a time
--> demo.rs:24:5
|
23 | a.x();
| - first mutable borrow occurs here
24 | a.x();
| ^
| |
| second mutable borrow occurs here
| first borrow later used here
I'm a bit puzzled. Why would a.x()
be a borrow at all, I thought let mut a
would be the only borrow here.
The x
method takes &'a mut self
, so it must borrow the A
struct for the same lifetime as the references stored inside of the struct. This must be at least as long as the struct's own lifetime, since you can't store short-lived references in a long-lived struct:
fn x(&'a mut self)
As you've seen, taking an unique reference to a struct and storing it within that struct effectively locks that struct for its entire lifetime, preventing any other use of the struct, ever.
One way around this is to use a type like RefCell
so that x
can take a shared reference instead of a unique reference:
use std::cell::RefCell;
struct A<'a> {
b: &'a mut B,
v: RefCell<Vec<&'a B>>,
}
impl<'a> A<'a> {
fn x(&'a self) {
self.v.borrow_mut().push(self.b);
}
}
1 Like
I'll add that, in general, circular references and self-referential structures are a tricky case for Rust's type system, and many Rust programming techniques are about avoiding such structures completely.
1 Like
Thank you very much! I'll try to rethink the way I structured it. But it was nevertheless important to understand the problem here (to the extent I actually understand it, that is ).