了解 Rc<RefCell<SomeStruct>> 在 Rust 中的用法

Gue*_*OCs 6 rust

我正在查看一些使用的代码

Rc<RefCell<SomeStruct>>
Run Code Online (Sandbox Code Playgroud)

所以我出去阅读了 Rc 和 RefCell 之间的差异:

以下是选择 Box、Rc 或 RefCell 的原因的概述:

Rc 使同一数据的多个所有者成为可能;Box 和 RefCell 有一个所有者。

Box 允许在编译时检查不可变或可变借用;Rc 只允许在编译时检查不可变借用;

RefCell 允许在运行时检查不可变或可变借用。因为 RefCell 允许在运行时检查可变借用,所以即使 RefCell 是不可变的,您也可以改变 RefCell 内的值。

因此,请Rc确保SomeStruct可供多人同时访问。但我如何访问?我只看到get_mut返回可变引用的方法。但是文本解释了“Rc 只允许不可变的借用”。

如果可以以 mut 而不是 mut 方式访问 Rc 的对象,为什么需要 RefCell?

Sve*_*ach 11

因此,请Rc确保SomeStruct可供多人同时访问。但我如何访问?

通过解引用。如果您有一个x类型为 的变量Rc<...>,则可以使用*x. 在许多情况下,这是隐式发生的;例如,您可以x简单地使用x.method(...).

我只看到get_mut返回可变引用的方法。但是文本解释说“Rc只允许不可变的借用”。

get_mut()方法可能比Rc仅允许不可变借用的解释更新。此外,如果当前只有一个内部值的所有者,即如果您目前首先不需要,它只返回可变借用Rc。一旦有多个所有者,get_mut()将返回None

如果可以以Rcmut 而不是 mut 方式访问的对象,为什么RefCell需要 a ?

RefCell即使存在多个所有者,也允许您获得可变访问权限,即使您只持有对RefCell. 它会在运行时动态检查在任何给定时间只存在一个可变引用,如果您请求第二个并发引用(或方法的返回和错误try_borrow,分别),它会发生恐慌。不提供此功能Rc

所以总而言之,Rc给你共享所有权。内部值有多个所有者,只要至少有一个所有者仍然持有它,引用计数就可以确保数据保持活动状态。如果您的数据没有明确的单一所有者,这将非常有用。RefCell为您提供内部可变性,即您可以在运行时动态借用内部值,即使使用共享引用也可以修改它。该组合Rc<RefCell<...>>为您提供了两者的组合 - 具有多个所有者的价值,可以由任何一个所有者可变地借用。

更详细的可以阅读 Rust 书的相关章节:

  • “RefCell”本身只有一个所有者。即使您只有“RefCell”的共享引用,它也允许您获取对内部值的可变引用。另一方面,“Rc”允许共享所有权。指针对象被分配在堆上,并且只要仍然有任何引用就存在。这些概念彼此完全正交,并且通常能够很好地互补。 (2认同)