-
Pin是一个结构 struct,Unpin是一个特征 trait。 -
Pin结构体的唯一成员是一个指针(例如引用和Box)。它禁止外界获取指向数据的可变引用,从而保证指向的数据不被移动。 -
Unpin代表数据可以被安全地移动,!Unpin则反之。通常!Unpin的都是自引用类型。 -
可以通过引入一个
std::marker::PhantomPinned成员来为结构体实现!Unpin。这个标记类型本身是!Unpin的,一旦结构体包含了!Unpin成员,那么整个结构体就会是!Unpin。 -
只有当存放的数据是
!Unpin类型指针时,Pin的特性才会生效。如果一个Unpin类型的指针被放入Pin中,则这个操作是没有实际意义的,Pin也不会阻止数据移动。在这种情况下Pin<&mut u8>和&mut u8几乎没有区别。 -
async 函数返回的 Future 默认就是
!Unpin的,但是很多时候我们需要一个Unpin的 Future。解决方法是将 Future 通过<Box>固定到堆上,就能是Unpin了,再通过Pin保证其不被移动,即最终获取一个Pin<Box<Future>>。例如常见的约束可能是:
fn execute_unpin_future(x: impl Future那么
Pin<Box<Fut>>即满足了impl Future,又能实现Unpin. -
也可以
Pin到栈上,但是除非是Unpin的类型,否则就必须使用 unsafe(Pin::new_uncheckedorstd::pin::pin!)。此外,函数返回时栈帧会释放,而且 rust 编译优化可能会在栈帧内移动数据。因此,尽量不要这么做。
暂无评论
