问题
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 drop
s?
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