Cell 只是一个内联存储/包装类型,它控制内部类型 T 的可变性/访问语义并提供内部可变性功能。从Rust 文档 Deref来看,该类型并未实现Cell<T>。为什么是这样 ?的实例Cell<T>始终处于有效状态(内存始终有效且已初始化)。这意味着在实施时Deref不可能Cell<T>出现恐慌,这是实施的要求之一Deref。
提供一个Derefimpl forCell<T>会很方便。
FZs*_*FZs 17
但这是不健全的!
的前提Cell是它永远不会给出对其内容的引用(事实上,这就是它的兄弟RefCell所做的),因此对它的所有读写操作都是原子的1。
作为其实现的一部分,Cell有一个set具有以下签名的方法:
fn set(&self, val: T)
Run Code Online (Sandbox Code Playgroud)
...这会更改 的值,即共享引用2&Cell<T>后面的单元格的值。这就是内部可变性的工作原理。
现在想象一下您可以创建对以下内容的引用Cell:
let cell = Cell::new(1);
let one: &i32 = &*cell;
Run Code Online (Sandbox Code Playgroud)
...其他人调用了该set方法:
cell.set(2);
Run Code Online (Sandbox Code Playgroud)
现在我们已经改变了共享引用()所指向的数据&T,即 UB 3!
println!("one = {}", *one); // one = 2 !!!
Run Code Online (Sandbox Code Playgroud)
1:不是“线程安全”意义上的
2:它可以通过使用UnsafeCell一个内置编译器来很好地做到这一点:“相信我编译器,我可以强制执行借用规则,所以你不必这样做”
3:在(之外不知道)UnsafeCell&TCell
| 归档时间: |
|
| 查看次数: |
149 次 |
| 最近记录: |