当前位置: 首页>>编程示例 >>用法及示例精选 >>正文


Rust Pin.new_unchecked用法及代码示例

本文简要介绍rust语言中 core::pin::Pin.new_unchecked 的用法。

用法

pub unsafe fn new_unchecked(pointer: P) -> Pin<P>

围绕对可能实现或不实现 Unpin 的类型的某些数据的引用构造一个新的 Pin<P>

如果 pointer 取消对 Unpin 类型的引用,则应改为使用 Pin::new

安全性

这个构造函数是不安全的,因为我们不能保证 pointer 指向的数据是固定的,这意味着数据在被删除之前不会被移动或它的存储无效。如果构造的 Pin<P> 不保证 P 指向的数据是固定的,则违反 API 合同,并可能导致以后(安全)操作中的未定义行为。

通过使用这种方法,您承诺P::DerefP::DerefMut实现(如果存在)。最重要的是,他们不能搬出他们的self参数:Pin::as_mutPin::as_ref将会通知DerefMut::deref_mutDeref::deref 在固定的指针上并期望这些方法能够维护固定不变式。此外,通过调用此方法,您承诺参考P对的取消引用不会再次被移出;特别是,它一定不可能获得&mut P::Target然后移出该参考(例如,使用core::mem::swap)。

例如,在 &'a mut T 上调用 Pin::new_unchecked 是不安全的,因为虽然您可以在给定的生命周期内固定它 'a ,但您无法控制它是否在 'a 结束后保持固定:

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);
        // This should mean the pointee `a` can never move again.
    }
    mem::swap(&mut a, &mut b);
    // The address of `a` changed to `b`'s stack slot, so `a` got moved even
    // though we have previously pinned it! We have violated the pinning API contract.
}

一个值一旦固定,就必须永远固定(除非它的类型实现了 Unpin )。

同样,在 Rc<T> 上调用 Pin::new_unchecked 也是不安全的,因为可能存在不受固定限制的相同数据的别名:

use std::rc::Rc;
use std::pin::Pin;

fn move_pinned_rc<T>(mut x: Rc<T>) {
    let pinned = unsafe { Pin::new_unchecked(Rc::clone(&x)) };
    {
        let p: Pin<&T> = pinned.as_ref();
        // This should mean the pointee can never move again.
    }
    drop(pinned);
    let content = Rc::get_mut(&mut x).unwrap();
    // Now, if `x` was the only reference, we have a mutable reference to
    // data that we pinned above, which we could use to move it as we have
    // seen in the previous example. We have violated the pinning API contract.
 }

相关用法


注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 core::pin::Pin.new_unchecked。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。