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


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