viraptor
viraptor

Reputation: 34205

Using vec in a struct

I've got a struct holding a vec of similar structs:

struct ProcessNode {
    ...
    children: Vec<Rc<ProcessNode>>,
}

Unfortunately when I try to append something into the vec, I'm running into an issue:

let mut parent_node: &mut Rc<ProcessNode> = ...
let mut parent_children: &mut Vec<Rc<ProcessNode>> = &mut parent_node.children;

Now the parent_node checks out during compilation, but parent_children cannot be referenced that way. Why? And how can I append to a vec field in a structure?

Upvotes: 0

Views: 2020

Answers (1)

Freyja
Freyja

Reputation: 40914

I'm assuming this is the error message that you're getting?

error[E0596]: cannot borrow data in a `&` reference as mutable
  --> src/main.rs:11:58
   |
11 |     let mut parent_children: &mut Vec<Rc<ProcessNode>> = &mut parent_node.children;
   |                                                          ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable

Since Rc<T> gives you the ability to have multiple objects point to the same data, it will only allow you to get an immutable reference to its content, otherwise the borrow checker wouldn't be able to guarantee that it won't be changed somewhere in the code while it's borrowed somewhere else.

The way around this is typically to use Rc<RefCell<T>>, which is a container type that allows you to get a mutable reference to the data with an immutable reference, and do borrow checking at runtime instead of compile time:

let parent_node: &Rc<RefCell<ProcessNode>> = ...;

// get a mutable reference to the ProcessNode
// (this is really a RefMut<ProcessNode> wrapper, and this needs to be in scope for as
// long as the reference is borrowed)
let mut parent_node_mut: RefMut<'_, ProcessNode> = parent_node.borrow_mut();

// get mutable reference to children
let parent_children: &mut Vec<_> = &mut parent_node_mut.children;

Playground example

You can read more about using RefCell with Rc in the documentation here

Upvotes: 2

Related Questions