pin-self-referential
Pin 与自引用类型
背景
某些类型一旦构造,其中的指针/引用指向自身内部数据;若对象移动则引用失效(悬垂)。Rust 默认可移动,需要“固定”以保证地址稳定。
Unpin 与 Pin
Unpin
:类型可以安全地被移动(大多数类型默认实现)。Pin<P<T>>
:对T
做“不动性”承诺,前提 是T: !Unpin
或我们希望强制其不被移动。- 常见容器:
Pin<Box<T>>
、Pin<&mut T>
、Pin<Arc<T>>
。
构造:
use std::pin::Pin;
let x = Box::pin(/* T 值 */); // 将 T 固定在堆上
let p: Pin<Box<T>> = x;
自引用与投影(Projection)
对 Pin<&mut T>
获取字段的可变引用并保持“不动性”不变式需要“投影”。推荐使用:
pin-project
或pin-project-lite
宏,安全地为字段生成Pin
投影。
use pin_project::pin_project;
use std::pin::Pin;
#[pin_project]
struct MyFut {
#[pin]
inner: SomeFuture,
buf: Vec<u8>,
}
impl std::future::Future for MyFut {
type Output = ();
fn poll(self: Pin<&mut Self>, cx: &mut std::task::Context<'_>) -> std::task::Poll<()> {
let this = self.project();
// this.inner 的类型为 Pin<&mut SomeFuture>
this.inner.poll(cx)
}
}