本文簡要介紹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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。