ManuallyDrop is a wrapper to inhibit compiler from automatically calling T’s destructor. This wrapper is 0-cost.
ManuallyDrop可以防止compiler在当被wrapper的变量销毁的时候调用变量的Drop函数,啥意思?用代码表述比较容易理解
let mut v = ManuallyDrop::new(vec![65,122]);
// 假如这里v goes out of scope,vec v将不会被drop
let _ = ManuallyDrop::into_inner(v);
// into_inner将 v转换回Vec,当v goes out of scope, v即被drop
这有什么用?
当要对fd进行操作的时候,比如,我需要open一个file,拿到file handle后,从file handle中取出fd,再对fd进行操作
fn get_fd() -> RawFd {
let f = File::open("file").unwrap();
let fd = f.as_raw_fd();
fd
}
fn main() {
let fd = get_fd();
let mut f = unsafe {File::from_raw_fd(fd)};
let mut s = String::new();
f.read_to_string(&mut s).unwrap();
}
这样写会导致panic,因为当get_fd函数返回时,File对象f将被销毁,同时会调用File的Drop实现,将underlying fd close掉,当后面再从from_raw_fd恢复File时,fd已经时badfd
所以get_fd需要在open后用ManuallyDrop将f包起来,这样当f被销毁时,fd不会被close掉
fn get_fd() -> RawFd {
let f = File::open("file").unwrap();
let f = ManuallyDrop::new(f);
let fd = f.as_raw_fd();
fd
}