需要关于Rust的细胞和参考计数类型的整体解释

时间:2017-08-14 12:23:47

标签: rust

Rust标准库中有几种包装类型:

据我所知,这些包装器提供了比简单参考更多的可能性。虽然我理解了一些基础知识,但我看不到整体情况。

他们到底做了什么?细胞和参考计数的家族是否提供正交或类似的特征?

2 个答案:

答案 0 :(得分:119)

Rust中有两个基本概念:

  • 所有权,
  • 可变性。

各种指针类型(BoxRcArc)与所有权有关:它们允许控制是否有单个或多个所有者单个对象。

另一方面,各种单元格(CellRefCellMutexRwLockAtomicXXX)与 Mutability < / em>的

Rust的安全性的基本规则是别名XOR可变性。也就是说,如果没有对其内部的未完成引用,则只能安全地改变对象。

此规则通常在编译时由借用检查程序执行:

  • 如果您有&T,则您不能在范围内对同一个对象&mut T
  • 如果你有&mut T,你也不能在范围内对同一个对象有任何引用。

然而,有时候,这还不够灵活。有时你需要(或想要)能够对同一个对象进行多次引用然后改变它。输入单元格

CellRefCell的想法是允许以受控方式存在别名的可变性

  • Cell阻止形成对其内部的引用,避免悬空引用,
  • RefCell别名XOR Mutability 的强制执行从编译时转移到运行时。

此功能有时被描述为提供内部可变性,这是一个实际上可以突变从外部(&T)看起来不可变的对象。

当此可变性扩展到多个线程时,您将使用MutexRwLockAtomicXXX;它们提供相同的功能:

  • AtomicXXX只是Cell:没有引用内部,只是移入/移出,
  • RwLock只是RefCell:可以通过警卫获取对内部的引用
  • MutexRwLock的简化版本,不区分只读后卫和写保护;因此在概念上类似于只有RefCell方法的borrow_mut

如果你来自C ++背景:

  • Boxunique_ptr
  • Arcshared_ptr
  • Rcshared_ptr的非线程安全版本。

细胞提供与mutable类似的功能,除了有额外的保证以避免混叠问题;将Cell视为std::atomic,将RefCell视为std::shared_mutex的非线程安全版本(如果采取锁定则抛出而不是阻止)。

答案 1 :(得分:6)

感谢Matthieu's good answer,这是一个帮助人们找到所需包装器的图表:

+-----------+
| Ownership |
+--+--------+                              +================+
   |                         +-Static----->| T              |(1)
   |                         |             +================+
   |                         |
   |                         |             +================+
   |          +-----------+  | Local    Val| Cell<T>        |(1)
   +-Unique-->| Borrowing +--+-Dynamic---->|----------------|
   |          +-----------+  |          Ref| RefCell<T>     |(1)
   |                         |             +================+
   |                         |
   |                         |             +================+
   |                         | Threaded    | AtomicT        |(2)
   |                         +-Dynamic---->|----------------|
   |                                       | Mutex<T>       |(1)
   |                                       | RwLock<T>      |(1)
   |                                       +================+
   |
   |
   |                                       +================+
   |                         +-No--------->| Rc<T>          |
   |                         |             +================+
   | Locally  +-----------+  |
   +-Shared-->| Mutable?  +--+             +================+
   |          +-----------+  |          Val| Rc<Cell<T>>    |
   |                         +-Yes-------->|----------------|
   |                                    Ref| Rc<RefCell<T>> |
   |                                       +================+
   |
   |
   |                                       +================+
   |                         +-No--------->| Arc<T>         |
   |                         |             +================+
   | Shared   +-----------+  |
   +-Between->| Mutable?  +--+             +================+
     Threads  +-----------+  |             | Arc<AtomicT>   |(2)
                             +-Yes-------->|----------------|
                                           | Arc<Mutex<T>>  |
                                           | Arc<RwLock<T>> |
                                           +================+
  1. 在这些情况下,T可以替换为Box<T>
  2. Tbool或数字
  3. 时使用AtomicT

    要知道您是应该使用Mutex还是RwLock,请参阅this related question