本文简要介绍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 MaybeUninit.assume_init_ref用法及代码示例
- Rust MaybeUninit.assume_init_read用法及代码示例
- Rust MaybeUninit.assume_init用法及代码示例
- Rust MaybeUninit.as_ptr用法及代码示例
- Rust MaybeUninit.as_mut_ptr用法及代码示例
- Rust MaybeUninit.array_assume_init用法及代码示例
- Rust MaybeUninit.write_slice用法及代码示例
- Rust MaybeUninit.zeroed用法及代码示例
- Rust MaybeUninit.write_slice_cloned用法及代码示例
- Rust MaybeUninit.write用法及代码示例
- Rust MaybeUninit.uninit用法及代码示例
- Rust MaybeUninit.new用法及代码示例
- Rust MaybeUninit.uninit_array用法及代码示例
- Rust MaybeUninit用法及代码示例
- Rust ManuallyDrop用法及代码示例
- Rust ManuallyDrop.into_inner用法及代码示例
- Rust ManuallyDrop.new用法及代码示例
- Rust Map用法及代码示例
- Rust Mutex.new用法及代码示例
- Rust MetadataExt.st_ctime_nsec用法及代码示例
- Rust MetadataExt.mtime_nsec用法及代码示例
- Rust MetadataExt.nlink用法及代码示例
- Rust MulAssign.mul_assign用法及代码示例
- Rust Mutex.get_mut用法及代码示例
- Rust MetadataExt.st_atime用法及代码示例
注:本文由纯净天空筛选整理自rust-lang.org大神的英文原创作品 std::mem::MaybeUninit.assume_init_mut。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。