6 个版本
0.1.5 | 2022 年 5 月 4 日 |
---|---|
0.1.4 | 2021 年 9 月 21 日 |
#13 in #interior-mutability
14KB
251 行
NearSafeCell
,一个更便捷的 UnsafeCell
包装/替代品。
原因
标准的 UnsafeCell
API 在某些情况下并不是很好用。
- 从
&T
获取&UnsafeCell<T>
没有使用简单且始终安全的unsafe{ &*cell.get() };
。 UnsafeCell::get
返回一个&mut T
,无论如何都需要不安全地解引用和重新引用来使用,所以为什么不直接返回一个引用并使函数本身不安全呢?UnsafeCell::get
的命名与自身和标准库的其他部分混淆且不一致 - 它应该真正地称为UnsafeCell::get_mut_ptr
。- 如果您确实只需要一个指针(例如作为映射键),您可以直接使用
&self as *const T
。根本不需要UnsafeCell
。
使用方法
use near_safe_cell::NearSafeCell;
// Implements 'Default'
let mut cell: NearSafeCell<usize> = NearSafeCell::default();
cell = NearSafeCell::new(24);
// Implements all Formatting traits
assert_eq!(format!("{:b}", cell), "11000");
assert_eq!(format!("{:?}", cell), "NearSafeCell(24)");
// Implements 'AsRef', 'AsMut', 'Deref' and 'DerefMut'
assert_eq!(cell.as_ref(), &24);
assert_eq!(cell.as_mut(), &mut 24);
assert_eq!(&*cell, &24);
assert_eq!(&mut *cell, &mut 24);
// You can still get pointers.
let const_ptr: *const usize = cell.get_ptr(); // &self
let mut_ptr: *mut usize = cell.get_mut_ptr(); // &self
// Safety: 'interiorly_mutable' is dropped before retrieving 'shared'.
let interiorly_mutable: &mut usize = unsafe{ cell.get_mut_unsafe() }; // &self
assert_eq!(interiorly_mutable, &mut 24);
*interiorly_mutable = 42;
drop(interiorly_mutable);
// Multiple shared references.
let shared: &usize = cell.get(); // &self
let shared2: &usize = cell.get(); // &self
assert_eq!(shared, &42);
assert_eq!(shared, shared2);
// One mutable reference.
let mutable: &mut usize = cell.get_mut(); // &mut self
assert_eq!(mutable, &mut 42);
*mutable = 242;
// Consuming the cell to get the value.
let value: usize = cell.unwrap(); // self
assert_eq!(value, 242);