rust 为什么`Deref`没有在`Cell `上实现< T>?

rn0zuynd  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(102)

Cell只是一个内嵌存储/ Package 类型,它控制内部类型T的可变性/访问语义,并提供内部可变性功能。根据rust文档,Deref没有为Cell<T>类型实现。为什么会这样呢?Cell<T>的示例始终处于有效状态(内存始终有效且已初始化)。这意味着当在Cell<T>上实现Deref时,它不可能死机,这是实现Deref的要求之一。
Cell<T>提供一个Deref impl会很方便。

55ooxyrt

55ooxyrt1#

但这是不合理的!
Cell的前提是它 * 从不 * 给出对其内容的引用(实际上,这正是它的兄弟*Ref*Cell所做的),因此对它的所有读写操作都是原子的。
作为其实现的一部分,Cell有一个set方法,其签名如下:

fn set(&self, val: T)

这会改变&Cell<T>的值,即共享引用后面的单元格的值2.这就是内在可变性的工作原理。
现在想象一下,你可以创建一个对Cell内容的引用:

let cell = Cell::new(1);

let one: &i32 = &*cell;

......还有人调用了set方法:

cell.set(2);

现在我们已经变异了一个共享引用(&T)指向的数据,它是UB 3!

println!("one = {}", *one); // one = 2 !!!

Playground link
1:不是“线程安全”意义上的
2:它可以通过使用UnsafeCell来很好地做到这一点:一个编译器内置说:“相信我编译器,我可以强制执行借用规则,所以你不必”
3:UnsafeCell的 * 外部 *(&T不知道Cell

相关问题