Rust标准库中有几种包装器类型:
std::cell模块中的单元格:Cell和RefCell- 引用计数的包装器,如
Rc和Arc。 - 中相应的类型的
std::sync模块:Mutex或AtomicBool例如
据我了解,这些包装器提供了比简单参考更多的可能性。虽然我了解一些基本知识,但看不到整个图片。
他们到底在做什么?细胞和参考计数家族是否提供正交或相似特征?
Rust标准库中有几种包装器类型:
std::cell模块中的单元格:Cell和RefCellRc和Arc。std::sync模块:Mutex或AtomicBool例如据我了解,这些包装器提供了比简单参考更多的可能性。虽然我了解一些基本知识,但看不到整个图片。
他们到底在做什么?细胞和参考计数家族是否提供正交或相似特征?
Answers:
Rust中有两个基本概念:
的各种指针类型(Box,Rc,Arc)所关心的所有权:它们允许控制是否有单个或多个所有者的单个对象。
在另一方面,各种细胞(Cell,RefCell,Mutex,RwLock,AtomicXXX)所关注的可变性。
Rust的安全性的基本准则是Aliasing XOR Mutability。也就是说,只有在对象内部没有显着引用的情况下,才可以安全地对其进行突变。
通常,借阅检查器会在编译时强制执行以下规则:
&T,则&mut T范围内的同一对象也不能具有,&mut T,则您也不能在范围内对同一对象有任何引用。但是,有时这不够灵活。有时您确实需要(或想要)具有对同一个对象的多个引用并对其进行突变的能力。输入单元格。
的思想Cell和RefCell是允许在可变性混叠的存在以受控的方式:
Cell 防止形成对内部的参照,避免悬挂的参照,RefCell将“别名XOR可变性”的实施从编译时间转移到运行时。有时将这种功能描述为提供内部可变性,也就是说,&T实际上可以改变从外部看起来不可变的对象的位置。
当这种可变性在多个线程扩展,您将改为使用Mutex,RwLock或AtomicXXX; 它们提供相同的功能:
AtomicXXX只是Cell:没有提及内部,只是移进/移出,RwLock公正RefCell:可以通过守卫获得对内饰的参考,Mutex是简化版本,RwLock不区分只读保护和写保护;因此在概念上类似于RefCell仅使用borrow_mut方法的。如果您来自C ++背景:
Box是unique_ptr,Arc是shared_ptr,Rc是的非线程安全版本shared_ptr。单元提供与相似的功能mutable,除了额外的保证以避免混叠问题。可以Cell将std::atomic和RefCell视为非线程安全版本std::shared_mutex(如果采用了锁定,则抛出该异常而不是阻塞该异常)。
感谢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>> |
+================+
T可以替换为Box<T>AtomicT时,T是一个bool或数要知道是否应使用Mutexor RwLock,请参阅此相关问题。