gpt4 book ai didi

rust - 为什么 Rust 需要 "a value, once pinned, must remain pinned forever"?

转载 作者:行者123 更新时间:2023-12-03 11:26:27 26 4
gpt4 key购买 nike

我对 Pin<P> 的要求感到困惑那个

a value, once pinned, must remain pinned forever.

我看到了the discussion thread on reddit但看完之后我仍然感到困惑。

对我来说,如果我们要求在 Pin<P> 时固定指针对象,感觉会更自然。对象还活着,但可以在 Pin<P> 之后重新获得再次移动它的能力对象被丢弃。

举个具体的例子,

use std::mem;
use std::pin::Pin;

fn move_pinned_ref<T>(mut a: T, mut b: T) {
unsafe {
let p: Pin<&mut T> = Pin::new_unchecked(&mut a);
// *I prefer* it to mean that the pointee `a` cannot move when `p` is in the scope.
// But *actually* it means the pointee `a` can never move again.
}

mem::swap(&mut a, &mut b);
// *I prefer* it to be valid because `p` has been dropped.
// But we *actually* have violated the pinning API contract that a value,
// once pinned, must remain pinned forever.
}

有人可以指出为什么我喜欢的设计有问题吗?

最佳答案

此规则的一个重要原因是它允许自引用结构保持有效,即使在 Pin 被删除后也是如此。例如:

use std::marker::PhantomPinned;
use std::pin::Pin;
use std::ptr::NonNull;

struct Unmovable {
data: String,
slice: Option<NonNull<String>>,
_pin: PhantomPinned,
}

impl Unmovable {
fn update_slice(self: Pin<&mut Self>) {
unsafe {
let self_mut = Pin::get_unchecked_mut(self);
self_mut.slice = Some(NonNull::from(&mut self_mut.data));
}
}

fn print_slice(&self) {
if let Some(s) = self.slice {
unsafe {
println!("{}", s.as_ref());
}
}
}
}

fn main() {
let mut a = Unmovable {
data: "Hello, world!".into(),
slice: None,
_pin: PhantomPinned,
};

let p = unsafe { Pin::new_unchecked(&mut a) };
p.update_slice(); // This causes `p` to be dropped.

// If we move `a`, even after dropping the Pin:

let x2 = Box::new(a);

// Now x2 has a dangling pointer!
x2.print_slice() // <-- Undefined behavior!
}

关于rust - 为什么 Rust 需要 "a value, once pinned, must remain pinned forever"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65519856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com