New*_*ewb 14 memory cell ownership rust borrow-checker
感兴趣为什么在最后一行set定义的方法显式地删除值。当函数返回时,它不应该被隐式删除(释放内存)吗?Cellold
use std::mem;
use std::cell::UnsafeCell;
pub struct Cell<T> {
value: UnsafeCell<T>
}
impl<T> Cell<T> {
pub fn set(&self, val: T) {
let old = self.replace(val);
drop(old); // Is this needed?
} // old would drop here anyways?
pub fn replace(&self, val: T) -> T {
mem::replace(unsafe { &mut *self.value.get() }, val)
}
}
Run Code Online (Sandbox Code Playgroud)
那么为什么不设置只这样做:
pub fn set(&self, val: T) {
self.replace(val);
}
Run Code Online (Sandbox Code Playgroud)
或者std::ptr::read做了一些我不明白的事情。
Loc*_*cke 10
这不是必需的,但在某些情况下drop显式调用可以帮助使代码更易于阅读。如果我们只将其编写为对 的调用,那么它看起来就像是 的包装函数,并且读者可能会丢失它在调用方法之上执行附加操作(删除先前值)的上下文。归根结底,使用哪个版本有些主观,并且在功能上没有区别。replacereplacereplace
话虽这么说,真正的原因是它在设置时并不总是删除以前的值。Cell<T>以前set通过不安全的指针操作实现覆盖现有值。后来在 rust-lang/rust#39264 中对其进行了修改:将 Cell 扩展到非复制类型,以便始终删除先前的值。作者 (wesleywiser) 可能想要更明确地表明,当将新值写入单元格时,先前的值将被删除,以便更容易审查拉取请求。
就我个人而言,我认为这是一个很好的用法,drop因为它有助于传达我们打算对该replace方法的结果执行的操作。