Is there any way to allow moving a container that has a borrowed element but not dropping it?

我们两清 提交于 2021-01-28 20:59:45

问题


I have this container:

use std::ptr::NonNull;

struct Container {
    data: NonNull<u8>,
}

impl Container {
    fn new() -> Container {
        todo!()
    }
    fn borrow_some_heap_data<'a>(&'a self) -> &'a u8 {
        todo!()
    }
    fn borrow_some_heap_data_mut<'a>(&'a mut self) -> &'a mut u8 {
        todo!()
    }
}

impl Drop for Container {
    fn drop(&mut self) {
        todo!()
    }
}

fn main() {
    let container = Container::new();
    let data = container.borrow_some_heap_data(); // or mut

    {
        let container = container; // move

        // This is safe because the move is a memcpy and the heap data doesn't change.
        println!("{}", *data);
    }

    // This is not safe because the container has been dropped
    // println!("{}", *data);
}
error[E0505]: cannot move out of `container` because it is borrowed
  --> src/main.rs:30:25
   |
27 |     let data = container.borrow_some_heap_data(); // or mut
   |                --------- borrow of `container` occurs here
...
30 |         let container = container; // move
   |                         ^^^^^^^^^ move out of `container` occurs here
...
33 |         println!("{}", *data);
   |                        ----- borrow later used here

Moving the container is safe even if there are references. Dropping it, however, is not safe. Is there any way to express this in Rust, to allow moves but not drops?

data is never deallocated until the struct is dropped.


回答1:


No, there is no way of doing this in safe Rust; the compiler is not intelligent enough / there's no syntax to distinguish the container's lifetime from the lifetimes of the elements.

From Why can't I store a value and a reference to that value in the same struct?:

There is a special case where the lifetime tracking is overzealous: when you have something placed on the heap. This occurs when you use a Box<T>, for example. In this case, the structure that is moved contains a pointer into the heap. The pointed-at value will remain stable, but the address of the pointer itself will move. In practice, this doesn't matter, as you always follow the pointer.



来源:https://stackoverflow.com/questions/64841409/is-there-any-way-to-allow-moving-a-container-that-has-a-borrowed-element-but-not

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!