有没有办法允许移动具有借用元素但不丢弃它的容器?

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

我有这个容器:

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

即使有引用,移动容器也是安全的。然而,丢弃它并不安全。有什么方法可以在 Rust 中表达这一点,允许移动但不允许 drops?

data 在结构被删除之前永远不会被释放。

不,在安全的 Rust 中无法做到这一点;编译器不够智能/没有语法来区分容器的生命周期和元素的生命周期。

来自

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.