本文简要介绍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 MaybeUninit.write_slice用法及代码示例
- Rust MaybeUninit.write_slice_cloned用法及代码示例
- Rust MaybeUninit.assume_init_mut用法及代码示例
- Rust MaybeUninit.as_ptr用法及代码示例
- Rust MaybeUninit.assume_init_ref用法及代码示例
- Rust MaybeUninit.zeroed用法及代码示例
- Rust MaybeUninit.assume_init用法及代码示例
- Rust MaybeUninit.as_mut_ptr用法及代码示例
- Rust MaybeUninit.array_assume_init用法及代码示例
- Rust MaybeUninit.uninit用法及代码示例
- Rust MaybeUninit.new用法及代码示例
- Rust MaybeUninit.uninit_array用法及代码示例
- Rust MaybeUninit.assume_init_read用法及代码示例
- 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.write。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。