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


Rust MaybeUninit.assume_init_mut用法及代碼示例


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

用法

pub unsafe fn assume_init_mut(&mut self) -> &mut T

獲取對包含值的可變(唯一)引用。

當我們想要訪問已初始化但沒有 MaybeUninit 所有權的 MaybeUninit (防止使用 .assume_init() )時,這可能很有用。

安全性

當內容尚未完全初始化時調用此方法會導致未定義的行為:由調用者來保證 MaybeUninit<T> 確實處於初始化狀態。例如, .assume_init_mut() 不能用於初始化 MaybeUninit

例子

此方法的正確用法:
use std::mem::MaybeUninit;

extern "C" {
    /// Initializes *all* the bytes of the input buffer.
    fn initialize_buffer(buf: *mut [u8; 1024]);
}

let mut buf = MaybeUninit::<[u8; 1024]>::uninit();

// Initialize `buf`:
unsafe { initialize_buffer(buf.as_mut_ptr()); }
// Now we know that `buf` has been initialized, so we could `.assume_init()` it.
// However, using `.assume_init()` may trigger a `memcpy` of the 1024 bytes.
// To assert our buffer has been initialized without copying it, we upgrade
// the `&mut MaybeUninit<[u8; 1024]>` to a `&mut [u8; 1024]`:
let buf: &mut [u8; 1024] = unsafe {
    // SAFETY: `buf` has been initialized.
    buf.assume_init_mut()
};

// Now we can use `buf` as a normal slice:
buf.sort_unstable();
assert!(
    buf.windows(2).all(|pair| pair[0] <= pair[1]),
    "buffer is sorted",
);
不正確此方法的用法:

您不能使用 .assume_init_mut() 來初始化值:

use std::mem::MaybeUninit;

let mut b = MaybeUninit::<bool>::uninit();
unsafe {
    *b.assume_init_mut() = true;
    // We have created a (mutable) reference to an uninitialized `bool`!
    // This is undefined behavior. ⚠️
}

例如,您不能將 Read 放入未初始化的緩衝區:

use std::{io, mem::MaybeUninit};

fn read_chunk (reader: &'_ mut dyn io::Read) -> io::Result<[u8; 64]>
{
    let mut buffer = MaybeUninit::<[u8; 64]>::uninit();
    reader.read_exact(unsafe { buffer.assume_init_mut() })?;
                            // ^^^^^^^^^^^^^^^^^^^^^^^^
                            // (mutable) reference to uninitialized memory!
                            // This is undefined behavior.
    Ok(unsafe { buffer.assume_init() })
}

也不能使用直接字段訪問來進行field-by-field 逐步初始化:

use std::{mem::MaybeUninit, ptr};

struct Foo {
    a: u32,
    b: u8,
}

let foo: Foo = unsafe {
    let mut foo = MaybeUninit::<Foo>::uninit();
    ptr::write(&mut foo.assume_init_mut().a as *mut u32, 1337);
                 // ^^^^^^^^^^^^^^^^^^^^^
                 // (mutable) reference to uninitialized memory!
                 // This is undefined behavior.
    ptr::write(&mut foo.assume_init_mut().b as *mut u8, 42);
                 // ^^^^^^^^^^^^^^^^^^^^^
                 // (mutable) reference to uninitialized memory!
                 // This is undefined behavior.
    foo.assume_init()
};

相關用法


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