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


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。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。