I have a data structure like this:
mod nodes {
struct Node {
predecessors: Vec<Rc<Node>>
}
}
I obviously don't need mutability of the nodes in that module. I also don't have cyclic references here.
But I have another module, which contains nodes, where I need mutability:
pub mod network {
mod nodes {...}
struct Network {
nodes: Vec<Vec<Rc<RefCell<Node>>>>
}
}
I just can't figure out a way to create the Rc<Node>
s for the nodes themselves together with the Rc<RefCell<Node>>
s for the Network
.
Do you have any idea on how to implement the immutability in the nodes
module next to the mutable nodes in the network
module?
Or is there no other way than to declare the references to the predecessor nodes inside the Node
struct as Rc<RefCell<Node>>
, even though I don't need mutability here (I would like to avoid that)?
Rust has single ownership. If a Node
is owned by a RefCell
, it cannot also be owned by a different Rc
at the same time.
When a Node
can be modified in one place via RefCell
, these changes cannot be allowed to show up elsewhere in Rc<Node>
. This would violate immutability of Rc<Node>
.
Also note that Node
is a struct value, not a pointer to an object. There's no extra layer of indirection that would even make it possible to share it between RefCell
and other Rc
. Its data is copied and inlined in its container.
Consider using Rc<RefCell<Node>>
in both places. If the same data is used in both places, it has to uphold all guarantees in both places, even if you're not taking advantage of that.
If you're not using both types at the same time, you can convert from one type to another by deconstructing it (into_inner
, try_unwrap
) and constructing the other type again. This conversion is not free, because physical memory layout of these types is different.
If you only sometimes need mutability, Rc
has make_mut
that works without RefCell
. And RefCell
has a zero-cost get_mut
if you already have a mutable access to it, so you might be able to reduce their overhead in specific cases.