我有这个容器:
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中表达这一点,允许移动,但不允许drop
?直到删除该结构,
data
才会释放。
最佳答案
不,没有办法在安全的Rust中执行此操作;编译器不够智能/没有语法可以区分容器的生存期和元素的生存期。
从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.
关于collections - 有什么方法可以允许移动具有借入元素但不能删除它的容器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64841409/