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
Nodeis owned by aRefCell, it cannot also be owned by a differentRcat the same time.When a
Nodecan be modified in one place viaRefCell, these changes cannot be allowed to show up elsewhere inRc<Node>. This would violate immutability ofRc<Node>.Also note that
Nodeis 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 betweenRefCelland otherRc. 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,
Rchasmake_mutthat works withoutRefCell. AndRefCellhas a zero-costget_mutif you already have a mutable access to it, so you might be able to reduce their overhead in specific cases.