直接回答:MaybeUninit 表示“可能未初始化”的内存,是 Rust 唯一合法的部分初始化工具。正确姿势四步:MaybeUninit::uninit() 或 uninit_array 拿空间 → 通过 as_mut_ptr() 写裸指针逐字段/逐元素初始化 → 写满后 assume_init() 转回 T → 若中途放弃(panic/错误)必须只 drop 已初始化部分。读未初始化内存永远是 UB,哪怕类型是整数。

展开解析:为什么是 UB:Rust 的类型有“有效值”要求,bool 只能是 0/1、引用必须非空对齐,未初始化字节读成这些类型立刻违反编译器假设,优化器可按任意方式处理;连整数理论上也可能因 poison/undef 语义出问题。老办法黑名单:mem::uninitialized()(已废弃,直接是 UB 发生器);先零初始化再覆盖(对含引用的类型零不是有效值,且多付一次写);用 MaybeUninit 但直接 &mut uninit.assume_init_mut() 当“占位引用”(造出指向未初始化内存的引用本身就是 UB)。实用模式:数组逐元素初始化用 uninit_array 加裸指针写,成功计数配合 guard——panic 时 guard 按计数 drop 已初始化前缀;部分初始化结构用 addr_of_mut! 宏取字段裸指针逐个写入(禁止中途造整体 &mut)。初始化完成的认定是“语义上的”:每个字节都被写过合法值,由你向编译器声明(assume_init)。Miri 对未初始化读有逐字节跟踪,写完务必跑一遍。

追问方向:为什么造指向未初始化内存的引用即 UB?数组初始化与结构体初始化哪个更难做对?

(约 480 字)