Rc<RefCell<T>>和RefCell<Rc<T>>有什么区别?

47
Rust文档详细介绍了Rc<RefCell<T>>,但没有涉及到RefCell<Rc<T>>,我现在遇到了这个问题。它们是否有效地产生了相同的结果?它们之间有重要的区别吗?

6
“which I am now encountering”翻译为“我现在正在遇到的”,“where are you encountering such a strange type?”翻译为“你在哪里遇到这样奇怪的类型?” - Shepmaster
1
@Shepmaster 我在书里看到了它(然后看到了这个问题)!当我在书中看到它时,感到非常惊讶。希望我误解了什么。https://doc.rust-lang.org/book/ch15-06-reference-cycles.html - ch271828n
好的,我知道了。在那个例子中,这种(不常见的)用法是正确的,且无法替换。 - ch271828n
1个回答

80
这两者是否能够有效地产生相同的结果?
它们是非常不同的。
Rc是一个具有共享所有权的指针,而RefCell提供了内部可变性。它们组合的顺序对于它们的使用方式有很大影响。
通常,你会将它们组合成Rc>;整个东西是共享的,每个共享所有者都可以改变内容。更改内容的效果将被外部Rc的所有共享所有者看到,因为内部数据是共享的。
你不能共享RefCell>,除非通过引用,因此这种配置在使用方式上更受限制。为了更改内部数据,您需要从外部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<RefCell<T>>要不实用。


我明白了。这是否意味着当您想要改变Rc指向的任何内容时,使用RefCell<Rc>? - Gman man
5
当你有一个 Rc 并且想要用另一个 Rc 替换它时,这将非常有用。原始 Rc 的任何克隆都不会受到影响。 - Peter Hall

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接