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

Fre*_*ios 67 rust

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

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

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

Mat*_* M. 124

Rust中有两个基本概念:

  • 所有权,
  • 可变性.

的各种指针类型(Box,Rc,Arc)所关心的所有权:它们允许控制是否有单个或多个所有者的单个对象.

在另一方面,各种细胞(Cell,RefCell,Mutex,RwLock,AtomicXXX)所关注的可变性.


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

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

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

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

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

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

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

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

  • AtomicXXX只是Cell:没有参考内部,只是进/出,
  • RwLock只是RefCell:可以通过警卫获得对内部的参考,
  • Mutex是一个简化版本,RwLock它不区分只读保护和写保护; 所以在概念上类似于RefCell只有一种borrow_mut方法.

如果你来自C++背景:

  • Box是的unique_ptr,
  • Arc是的shared_ptr,
  • Rc是一个非线程安全的版本shared_ptr.

mutable除了提供额外保证以避免混叠问题外,这些单元提供了类似的功能; 认为Cell作为std::atomicRefCell作为非线程安全版本std::shared_mutex(其抛出,而不是锁被采取拦截).

  • 也许口号应该使用NAND而不是XOR:P (10认同)
  • 如果**别名XOR Mutability**是安全规则,那意味着**(不是别名)和(不可变性)**是不安全的?但可以肯定的是,如果没有别名且没有可变性,那么这是完全安全的吗?我认为你想要的不仅仅是XOR. (5认同)
  • @Boiethios:是的,就是这样.每个引用/指针都是真实数据的"别名"(毕竟,同一个"人"的不同名称就是别名),并且在软件中我们讨论了当给定多个别名时的别名时间. (3认同)
  • 本书的第一版有[关于此的章节](https://doc.rust-lang.org/book/first-edition/choosing-your-guarantees.html).这是重写中遗失的一个,我认为这是不幸的 - 也许它应该被制作成附录或其他东西 (3认同)
  • 非常感谢你*,你回答我对Rust中"复杂"类型的所有困惑.与C++的比较也是完美的. (2认同)

Fre*_*ios 9

感谢Matthieu的好答案,这是一个帮助人们找到所需包装的图表:

+-----------+
| 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>> |
                                           +================+
Run Code Online (Sandbox Code Playgroud)
  1. 在那些情况下,T可以替换为Box<T>
  2. 使用AtomicT何时T是一个bool或一个数字

要知道您是否应该使用MutexRwLock,请参阅此相关问题.