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

问题描述 投票:64回答:2

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

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

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

rust
2个回答
119
投票

Rust中有两个基本概念:

  • 所有权,
  • 可变性。

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

另一方面,各种细胞(CellRefCellMutexRwLockAtomicXXX)与可变性有关。


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

此规则通常由借用检查器在编译时强制执行:

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

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

CellRefCell的想法是允许以受控方式存在混淆的可变性:

  • Cell防止形成对其内部的引用,避免悬挂引用,
  • RefCell将Aliasing XOR Mutability的执行从编译时转移到运行时。

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

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

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

如果你来自C ++背景:

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

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


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. AtomicTT或数字时,请使用bool

要知道你是否应该使用MutexRwLock,请参阅this related question

© www.soinside.com 2019 - 2024. All rights reserved.