Rc<RefCell<T>> 和 RefCell<Rc<T>> 有啥区别?

Posted

技术标签:

【中文标题】Rc<RefCell<T>> 和 RefCell<Rc<T>> 有啥区别?【英文标题】:What is the difference between Rc<RefCell<T>> and RefCell<Rc<T>>?Rc<RefCell<T>> 和 RefCell<Rc<T>> 有什么区别? 【发布时间】:2019-12-13 11:29:37 【问题描述】:

Rust 文档非常广泛地涵盖了Rc&lt;RefCell&lt;T&gt;&gt;,但没有涉及到我现在遇到的RefCell&lt;Rc&lt;T&gt;&gt;

这些是否有效地给出了相同的结果?它们之间有重要区别吗?

【问题讨论】:

我现在遇到的——你在哪里遇到这么奇怪的类型? @Shepmaster 我在书中看到(然后看到这个问题)!当我在书中看到它时,我感到很惊讶。希望我误解了一些东西doc.rust-lang.org/book/ch15-06-reference-cycles.html 好的,我知道。在该示例中,(不常见的)用法是正确且不可替代的。 【参考方案1】:

这些是否有效地给出了相同的结果?

它们非常不同。

Rc 是共享所有权的指针,而RefCell 提供内部可变性。它们的组成顺序对它们的使用方式有很大影响。

通常,您将它们编写为Rc&lt;RefCell&lt;T&gt;&gt;;整个事情都是共享的,每个共享所有者都可以改变内容。由于内部数据是共享的,所以外部Rc 的所有共享所有者都将看到更改内容的效果。

您不能通过引用共享RefCell&lt;Rc&lt;T&gt;&gt;,因此此配置的使用方式受到更多限制。为了改变内部数据,您需要可变地从外部RefCell 借用,但是您可以访问不可变 Rc。改变它的唯一方法是用完全不同的Rc 替换它。例如:

let a = Rc::new(1);
let b = Rc::new(2);

let c = RefCell::new(Rc::clone(&a));
let d = RefCell::new(Rc::clone(&a));

*d.borrow_mut() = Rc::clone(&b); // this doesn't affect c

没有办法改变ab 中的值。这似乎远不如Rc&lt;RefCell&lt;T&gt;&gt;有用。

【讨论】:

我明白了。这是否意味着 RefCell 当你有一个 Rc 并且我想用另一个替换它时。原始 Rc 的任何克隆都不会受到影响。 我真的很喜欢你展示RefCell&lt;Rc&lt;T&gt;&gt; 的工作方式。这是一个很好的答案。

以上是关于Rc<RefCell<T>> 和 RefCell<Rc<T>> 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

一个模块中有 Rc<T>s,另一个模块中有 Rc<RefCell<T>>s 引用相同的数据

如何将 Rc<RefCell<dyn T>> 传递给想要 &dyn T 的 fn?

Rayon 如何防止线程之间使用 RefCell<T>、Cell<T> 和 Rc<T>?

如何将 Rc<RefCell<_>> 中的具体对象转换为动态特征对象? [复制]

是否有替代方法或方法让 Rc<RefCell<X>> 限制 X 的可变性?

使用 RefCell 和 Rc 处理循环图中的内存泄漏