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-20 14:42:23 【问题描述】:Rust 文档非常广泛地涵盖了Rc<RefCell<T>>
,但没有涉及到我现在遇到的RefCell<Rc<T>>
。
这些是否有效地给出了相同的结果?它们之间有重要区别吗?
【问题讨论】:
我现在遇到的——你在哪里遇到这么奇怪的类型? @Shepmaster 我在书中看到(然后看到这个问题)!当我在书中看到它时,我感到很惊讶。希望我误解了一些东西doc.rust-lang.org/book/ch15-06-reference-cycles.html 好的,我知道。在该示例中,(不常见的)用法是正确且不可替代的。 【参考方案1】:这些是否有效地给出了相同的结果?
它们非常不同。
Rc
是共享所有权的指针,而RefCell
提供内部可变性。它们的组成顺序对它们的使用方式有很大影响。
通常,您将它们编写为Rc<RefCell<T>>
;整个事情都是共享的,每个共享所有者都可以改变内容。由于内部数据是共享的,所以外部Rc
的所有共享所有者都将看到更改内容的效果。
您不能通过引用共享RefCell<Rc<T>>
,因此此配置的使用方式受到更多限制。为了改变内部数据,您需要可变地从外部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
没有办法改变a
和b
中的值。这似乎远不如Rc<RefCell<T>>
有用。
【讨论】:
我明白了。这是否意味着 RefCellRefCell<Rc<T>>
的工作方式。这是一个很好的答案。以上是关于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<_>> 中的具体对象转换为动态特征对象? [复制]