一个模块中有 Rc<T>s,另一个模块中有 Rc<RefCell<T>>s 引用相同的数据
Posted
技术标签:
【中文标题】一个模块中有 Rc<T>s,另一个模块中有 Rc<RefCell<T>>s 引用相同的数据【英文标题】:Having Rc<T>s in one module and Rc<RefCell<T>>s in another referencing the same data 【发布时间】:2020-06-14 05:27:13 【问题描述】:我有这样的数据结构:
mod nodes
struct Node
predecessors: Vec<Rc<Node>>
我显然不需要该模块中节点的可变性。我这里也没有循环引用。
但我有另一个模块,其中包含我需要可变性的节点:
pub mod network
mod nodes ...
struct Network
nodes: Vec<Vec<Rc<RefCell<Node>>>>
我只是想不出一种方法来为节点本身创建Rc<Node>
s 以及为Network
创建Rc<RefCell<Node>>
s。
您对如何在network
模块中的可变节点旁边的nodes
模块中实现不变性有任何想法吗?
或者除了将Node
结构中的前驱节点的引用声明为Rc<RefCell<Node>>
之外没有其他方法,即使我在这里不需要可变性(我想避免这种情况)?
【问题讨论】:
【参考方案1】:Rust 有 single ownership。如果Node
由RefCell
拥有,则它不能同时由不同的Rc
拥有。
当Node
可以通过RefCell
在一处修改时,这些更改不能在Rc<Node>
的其他位置显示。这将违反Rc<Node>
的不变性。
还要注意Node
是一个结构值,而不是指向对象的指针。没有额外的间接层甚至可以在RefCell
和其他Rc
之间共享它。其数据被复制并内联在其容器中。
考虑在这两个地方使用Rc<RefCell<Node>>
。如果在两个地方使用相同的数据,它必须在两个地方都支持所有保证,即使您没有利用这一点。
如果您没有同时使用这两种类型,您可以通过解构它(into_inner
、try_unwrap
)并再次构造另一种类型来将其转换为另一种类型。这种转换不是免费的,因为这些类型的物理内存布局不同。
get_mut
的可变访问权限,那么 RefCell
的成本为零,因此您可以在特定情况下减少它们的开销。
【讨论】:
以上是关于一个模块中有 Rc<T>s,另一个模块中有 Rc<RefCell<T>>s 引用相同的数据的主要内容,如果未能解决你的问题,请参考以下文章