Nikolaos Georgiou
Nikolaos Georgiou

Reputation: 2874

Rust pattern for container object

I have a struct which owns various other structs, e.g.

pub struct Computer {
  monitor: Monitor,
  keyboard: Keyboard,
  mouse: Mouse,
  printer: Printer
}

some of these child objects require each other, which leads to build errors like "Cannot borrow as mutable more than once at a time".

self.mouse.change_orientation(&mut self.keyboard);

impl Mouse {
  fn change_orientation(&mut self, keyboard: &mut Keyboard) {  
    // ignore the fact that the example does not make much sense,
    // for some reason this method really needs to mutate both the mouse
    // and the keyboard
  }
}

I can imagine this is a common problem / pattern if you come from a more OOP background. There's a container object that owns smaller objects that perform different tasks. When one of these small objects needs a reference to another, the reference is tied to the container object as far as Rust is concerned.

How would you refactor this code so that it works with Rust? I'm a bit hesitant going full on with Rc<RefCell everything because I do like the benefits of the compile time borrow checker.

Edit: apologies, I have made a mistake. As pointed out in the comment, the example I provided actually works. My bad. What I was trying to do in my actual code was to pass the entire container as a mutable reference, which of course shouldn't work.

Upvotes: 0

Views: 277

Answers (1)

phimuemue
phimuemue

Reputation: 36031

Often, these things can be solved via borrow splitting: https://doc.rust-lang.org/nomicon/borrow-splitting.html

I.e. you explicitly make the compiler understand that you are mutating two separate entities.

Upvotes: 1

Related Questions