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


Rust MaybeUninit.write用法及代碼示例


本文簡要介紹rust語言中 std::mem::MaybeUninit.write 的用法。

用法

pub fn write(&mut self, val: T) -> &mut T

設置 MaybeUninit<T> 的值。

這會覆蓋任何先前的值而不刪除它,因此請注意不要使用它兩次,除非您想跳過運行析構函數。為方便起見,這還返回對 self (現已安全初始化)內容的可變引用。

由於內容存儲在 MaybeUninit 內部,因此如果 MaybeUninit 離開作用域而不調用 assume_init assume_init_drop 或類似內容,則不會為內部數據運行析構函數。接收此函數返回的可變引用的代碼需要記住這一點。 Rust 的安全模型認為泄漏是安全的,但它們通常仍然是不可取的。話雖這麽說,可變引用的行為就像任何其他可變引用一樣,因此為其分配新值將刪除舊內容。

例子

此方法的正確用法:

use std::mem::MaybeUninit;

let mut x = MaybeUninit::<Vec<u8>>::uninit();

{
    let hello = x.write((&b"Hello, world!").to_vec());
    // Setting hello does not leak prior allocations, but drops them
    *hello = (&b"Hello").to_vec();
    hello[0] = 'h' as u8;
}
// x is initialized now:
let s = unsafe { x.assume_init() };
assert_eq!(b"hello", s.as_slice());

該方法的這種用法會導致泄漏:

use std::mem::MaybeUninit;

let mut x = MaybeUninit::<String>::uninit();

x.write("Hello".to_string());
// This leaks the contained string:
x.write("hello".to_string());
// x is initialized now:
let s = unsafe { x.assume_init() };

在某些情況下,可以使用此方法來避免不安全。下麵的示例顯示了一個固定大小的 arena 實現的一部分,它借出固定引用。使用 write ,我們可以避免通過原始指針進行寫入:

use core::pin::Pin;
use core::mem::MaybeUninit;

struct PinArena<T> {
    memory: Box<[MaybeUninit<T>]>,
    len: usize,
}

impl <T> PinArena<T> {
    pub fn capacity(&self) -> usize {
        self.memory.len()
    }
    pub fn push(&mut self, val: T) -> Pin<&mut T> {
        if self.len >= self.capacity() {
            panic!("Attempted to push to a full pin arena!");
        }
        let ref_ = self.memory[self.len].write(val);
        self.len += 1;
        unsafe { Pin::new_unchecked(ref_) }
    }
}

相關用法


注:本文由純淨天空篩選整理自rust-lang.org大神的英文原創作品 std::mem::MaybeUninit.write。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。