Rust标准库中有几种包装类型:
std::cell模块中的单元格:Cell和RefCellRc和Arc.std::sync模块中的类型:Mutex或者AtomicBool例如据我了解,这些是包装器,提供了比简单参考更多的可能性.虽然我理解一些基础知识,但我看不到整体情况.
他们到底做了什么?细胞和参考计数家族是否提供正交或类似的特征?
Mat*_* M. 124
Rust中有两个基本概念:
的各种指针类型(Box,Rc,Arc)所关心的所有权:它们允许控制是否有单个或多个所有者的单个对象.
在另一方面,各种细胞(Cell,RefCell,Mutex,RwLock,AtomicXXX)所关注的可变性.
Rust的安全性的基本规则是别名XOR Mutability.也就是说,如果没有对其内部的未完成引用,则只能安全地改变对象.
此规则通常由借用检查器在编译时强制执行:
&T,你也不能&mut T在范围内拥有同一个对象,&mut T,你也不能在范围内对同一个对象有任何引用.但是,有时候,这还不够灵活.有时你需要(或想要)能够对同一个对象进行多次引用然后改变它.输入单元格.
的思想Cell和RefCell是允许在可变性混叠的存在以受控的方式:
Cell 防止形成对其内部的引用,避免悬挂引用,RefCell将Aliasing XOR Mutability的执行从编译时移到运行时.此功能有时被描述为提供内部可变性,即从外部(&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>> |
+================+
Run Code Online (Sandbox Code Playgroud)
T可以替换为Box<T>AtomicT何时T是一个bool或一个数字要知道您是否应该使用Mutex或RwLock,请参阅此相关问题.