ManuallyDrop is a wrapper to inhibit compiler from automatically calling T’s destructor. This wrapper is 0-cost.

    ManuallyDrop可以防止compiler在当被wrapper的变量销毁的时候调用变量的Drop函数,啥意思?用代码表述比较容易理解

    1. let mut v = ManuallyDrop::new(vec![65,122]);
    2. // 假如这里v goes out of scope,vec v将不会被drop
    3. let _ = ManuallyDrop::into_inner(v);
    4. // into_inner将 v转换回Vec,当v goes out of scope, v即被drop

    这有什么用?
    当要对fd进行操作的时候,比如,我需要open一个file,拿到file handle后,从file handle中取出fd,再对fd进行操作

    1. fn get_fd() -> RawFd {
    2. let f = File::open("file").unwrap();
    3. let fd = f.as_raw_fd();
    4. fd
    5. }
    6. fn main() {
    7. let fd = get_fd();
    8. let mut f = unsafe {File::from_raw_fd(fd)};
    9. let mut s = String::new();
    10. f.read_to_string(&mut s).unwrap();
    11. }

    这样写会导致panic,因为当get_fd函数返回时,File对象f将被销毁,同时会调用File的Drop实现,将underlying fd close掉,当后面再从from_raw_fd恢复File时,fd已经时badfd
    所以get_fd需要在open后用ManuallyDrop将f包起来,这样当f被销毁时,fd不会被close掉

    1. fn get_fd() -> RawFd {
    2. let f = File::open("file").unwrap();
    3. let f = ManuallyDrop::new(f);
    4. let fd = f.as_raw_fd();
    5. fd
    6. }