MaybeUninit.write() と代入
// Copyright 2026 Google LLC // SPDX-License-Identifier: Apache-2.0 use std::mem::MaybeUninit; fn main() { let mut buf = MaybeUninit::<String>::uninit(); // 初期化 buf.write(String::from("Hello, Rust!")); // 上書き buf.write(String::from("Hi again")); // 代入では MaybeUninit の値全体が置き換えられる。 buf = MaybeUninit::new(String::from("Goodbye")); // 内側の値がドロップされることを確認 let _ = unsafe { buf.assume_init() }; }
内側の値を置き換えると、drop のセマンティクスがほとんどの型と異なるため、 メモリリークを引き起こす可能性があります。MaybeUninit<T> はその T のデストラクタを呼び出しません。
MaybeUninit::write() は ptr::write を使います。これは古い内容を読み取ったり ドロップしたりせずに、その場でメモリを初期化します。メモリが未初期化である 可能性があるときには、これはまさに望ましい動作ですが、そこにすでに有効な値が 入っていた場合はリークすることも意味します。
代入、たとえば buf = MaybeUninit::new(value) は、MaybeUninit 全体を 置き換えます。古い MaybeUninit はムーブされたあとにドロップされますが、 MaybeUninit には T 用のデストラクタがないため、内側の値はドロップされません。 古いスロットに初期化済みの値が入っていた場合、それは write() と同様に リークします。
通常の drop 動作が必要な場合は、assume_init または関連するメソッドのいずれかを使って、 その値が初期化済みであることを Rust に伝える必要があります。