Rust标准库中有几种包装器类型:
std::cell
模块中的单元格:Cell
和RefCell
- 引用计数的包装器,如
Rc
和Arc
。 - 中相应的类型的
std::sync
模块:Mutex
或AtomicBool
例如
据我了解,这些包装器提供了比简单参考更多的可能性。虽然我了解一些基本知识,但看不到整个图片。
他们到底在做什么?细胞和参考计数家族是否提供正交或相似特征?
Rust标准库中有几种包装器类型:
std::cell
模块中的单元格:Cell
和RefCell
Rc
和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
或数要知道是否应使用Mutex
or RwLock
,请参阅此相关问题。