直接回答:union 是 C 式联合体:多个字段共享同一块内存,编译器不知道哪个字段当前有效,读字段是 unsafe——用于 FFI 对接 C union、实现空间紧凑的 tagged pointer、位级 reinterpret。ManuallyDrop 包装一个值并禁止自动 drop:用于 union 内的非 Copy 字段(union 不能自动析构成员)、精确控制析构时机(如自定义内存池)、避免临时所有权的双重释放。

展开解析:安全义务明细:union 的写入是安全的、读取 unsafe,因为读之前你必须用外部信息(tag 枚举、协议约定)确定当前有效变体——读错变体拿到的是 reinterpret 的垃圾,含 Drop 类型时直接 UB。含非 Copy 成员的 union 必须包 ManuallyDrop,析构责任转嫁给你:mem::forget 手动泄漏或 ManuallyDrop::drop 手动析构,二选一且恰好一次。ManuallyDrop 自身的坑:忘记 drop 即泄漏(safe 但浪费);重复 drop 即 double free(UB);从 ManuallyDrop 取所有权用 ManuallyDrop::take,take 之后原位置视为已移出。经典组合是手动实现 tagged union:enum 判别 + union 数据,判别决定读哪个变体——这正是编译器为 enum 做的事,手写版本(如 thin pointer 优化)把判别编码进指针低位。现代替代方案优先:位 reinterpret 用 to_bits/from_bits(浮点)或 transmute 之前先想 bytemuck 的 Pod 派生;FFI 只透传不解释时用 opaque 类型。union 与 ManuallyDrop 是工具箱底层,需求真实存在才碰。

追问方向:为什么 union 成员必须是 Copy 或 ManuallyDrop?transmute 与 union 读取的差别在哪?

(约 490 字)