gpt4 book ai didi

rust - 是否可以使用 Pin 在堆栈而不是堆上创建自引用结构?

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

是否可以在堆栈上分配自引用结构? pin文档显示了将结构固定在堆上的示例。我按照它写了相应的代码:

pub struct Cont {
pub f: i32,
// shall point to 'f' field
ptr_f: NonNull<i32>,
}

impl Cont {
pub fn read(&self) -> i32 {
unsafe { *self.ptr_f.as_ref() }
}

pub fn pinned(value: i32) -> Pin<Self> {
// ensures ptr_f = &f
}
}

fn main() {
let a = Cont::pinned(5);
let b = Cont::pinned(12);

assert_eq!(a.f, a.read());
assert_eq!(b.f, b.read());
}

但我不知道如何编写 Cont::pinned 函数,甚至不知道它是否是正确的签名(如果可能的话)。

最佳答案

but I don't know how to write the Cont::pinned function, or even if it's the right signature (if even possible).

Pin<P> 的类型参数始终是指针或引用;一个Pin从不拥有它的数据,除非通过拥有指针类型,如 Box .鉴于您希望将原始值保留在堆栈上,示例中函数的模拟是:

fn pinned(value: i32) -> Pin<&mut Self>;

但这是不可能的,因为函数不能返回对它创建的东西的引用——除非那个东西存储在堆上或静态内存中。所以,如果你要构造一个 Pin对于堆栈分配的值,您必须先创建未固定的值,以便引脚可以引用它。

也许您可能会尝试设计一个 API 来创建一个 Pin通过改变一些已经在堆栈上的数据:

let a: Option<Cont> = None;
let b: Option<Cont> = None;

let a = Cont::pinned(&mut a, 5);
let b = Cont::pinned(&mut b, 12);

但这样一来,该值的生命周期将比 pin 长,您只能在 pin 处于事件状态时强制执行 pin 保证,从而不合理

为了让它听起来像,您需要以某种方式强制在删除 pin 后无法访问原始值。这将导致 API 非常受限。例如:

fn main() {
// setup_conts creates the pinned Cont values and calls the closure
setup_conts(5, 12, |a: Pin<&mut Cont>, b: Pin<&mut Cont>| {
// a and b can only be used inside this closure
})
}

关于rust - 是否可以使用 Pin 在堆栈而不是堆上创建自引用结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64621062/

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