當前位置: 首頁>>編程示例 >>用法及示例精選 >>正文


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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。