Rod*_*igo 2 memory move-semantics rust
我正在编写与 C API 通信的 Rust 代码,并且我需要某个结构来拥有固定的内存地址。到目前为止,我发现:
Pin用于指针;pin_mut用于固定堆栈的宏;PhantomPinned,我不清楚。如果我理解正确,PhantomPinned这将是最容易使用的:只需将其作为成员即可使我的结构自动具有固定的内存地址。它是否正确?
你需要的是Pin. 它是一个防止对象移动的指针。
pin_mut!()只是一个宏,可以帮助您创建Pin实例而无需堆分配或unsafe代码。
PhantomPinned还有另一个虽然相关的目标。默认情况下,您的类型将实现该Unpin特征(除非它包含不实现的类型Unpin,但大多数类型都会实现)。这是有问题的,因为对于实现Unpin,的类型Pin没有影响:它不会阻止您移动它们。这是因为大多数类型不需要固定的内存地址。例如,考虑一下i32:即使您创建了Pin<&mut i32>,您也可以移动它,因为i32实现了Unpin,因为即使您移动它也不会发生任何不好的事情,并且不会验证任何数据。
因此,为了Pin有效,您需要 un-impl Unpin。这是通过包含一个不将Unpin自身实现为字段的字段或具有负 impl 来完成的(请参阅什么是 Rust 中的 auto 特征?):
impl !Unpin for MyType {}
Run Code Online (Sandbox Code Playgroud)
不幸的是,负面暗示是不稳定的。相反,标准库提供了PhantomPinned无成本的类型(ZST),但没有实现Unpin(它有一个负隐含,因为标准库允许使用不稳定的功能,所以它可以做到这一点)。现在,当您的类型包含它时,它也变得!Unpin如此。
总而言之,您需要将其包含PhantomPinned在您的结构中,这样它就不会是Unpin,并且您需要将它包装起来Pin,这样它就不可移动。