用真实运行验证栈与堆:地址分区(栈 0x16f…、堆 0x1012…、字面量/static/代码 0x1008…);栈向低地址增长;主线程栈 8176 KiB 约 43468 层、子线程约 10884 层,溢出是 abort;16 MiB 栈数组溢出而堆上没事;256 字节缓冲区栈 3.39 ns 对堆 12.25 ns。
用真实运行验证 Box、Rc、Arc 的内存布局:指针 8 字节、胖指针 16 字节、Option 不增加大小;堆块大小(Box<u64> 8、Rc/Arc<u64> 24 = 16 计数器 + 8 数据;Rc<str> 单块分配);偷看 (strong, weak) 计数器;数据在最后一个强引用 drop,内存块在最后一个 Weak 才释放。
用 aarch64 汇编对比验证零开销抽象:4 组高层写法与手写逐行相同(Newtype、Option<&T>、泛型、闭包),迭代器链差别很小;带来开销的是边界检查(11 条对 2 条)、checked_add、Rc 计数这类明确要求的安全;debug 构建里抽象不被内联,耗时 27.36 对 19.63 ms。
用 size_of、offset_of 与 transmute 验证 repr(C):(u8, u32, u16) repr(Rust) 8 字节(自动重排)对 repr(C) 12 字节(填充 5);声明顺序决定 24 对 16 字节;packed 7 字节但引用字段 E0793,align(16) 补到 16;枚举的 repr 大小;12 个真实字节的排布。
用 align_of 与编译器的 -Z print-type-sizes 验证对齐与填充:基本类型与结构体的 size/align;repr(C) MixedC 32 字节含 16 字节填充而默认布局 16 字节无填充(自动重排);Vec 元素间距 = size;read_unaligned 不对齐读 0.46 ns 对齐读 0.45 ns,直接解引用不对齐指针在 debug 下 panic。
用 size_of、-Z print-type-sizes 与 transmute 验证枚举布局:Option<u32> 8 字节而 Option<NonZeroU32>/bool/&T/Box/String 都不加大小(niche);Option 嵌套三层 bool 仍 1 字节;Shape 28 字节(标签 4 + 最大变体 24);Msg 24 字节(与 String 一样大,没有单独的标签字段);判别值与 E0605;Option<bool> 的 None 就是 2。
用 transmute 与 size_of_val 验证 trait object 的胖指针:dyn / 切片 / str 都是 16 字节(地址 + 元数据:vtable 或长度);转 *const () 丢元数据;vtable 与具体类型绑定;trait 上转型的数据地址与 vtable 观察;ptr::eq 比较;size_of_val 与 Drop 经 vtable;dyn Any 的 TypeId 向下转型。
用真实运行验证切片的胖指针:size 16(指针 + 长度);切出子切片只改指针与长度、不复制;改切片就改原数据,重叠的 &mut 切片报 E0499 而 split_at_mut 给出不重叠两半;三种越界 panic 的消息;100 万个零大小元素的切片 size_of_val 为 0、空切片指针是 0x8;chunks/windows/split_first 的偏移与长度。
用 transmute 与真实 libc 调用验证 Option<&T> 的空指针优化:Option<&T> / <&mut T> / <Box<T>> / <NonNull<T>> / <fn()> 的 None 都是 0x0、8 字节(裸指针的 Option 要 16 字节);getenv / strchr 返回 NULL 直接收成 None;Option<Box> 传给 free;自己手写「裸指针 + bool」的节点 24 字节而 Option<Box> 节点 16 字节。
用真实运行验证 MaybeUninit:普通变量读未初始化报 E0381;MaybeUninit<u64> 8 字节无标签;逐个 write 初始化 [String; 4] 并与 from_fn 对照;MaybeUninit 不自动 drop(泄漏)、部分初始化只能 drop 已初始化的;1 MiB 缓冲区清零 11.07 µs 对不清零 0.93 µs。
用真实运行验证 ManuallyDrop:不自动 drop、大小同 T、Deref 可用、手动 drop 与 into_inner;改变字段 drop 顺序;绕过 E0509 的 take 写法(into_data 不运行 Guard::drop);配合 Vec::from_raw_parts 避免双重释放;与 mem::forget 的区别。
用真实编译验证 unsafe 的边界:只多出五种能力(裸指针解引用、unsafe fn、static mut、union 字段都报 E0133,实现 unsafe trait 报 E0200);放进 unsafe 块全部通过;unsafe 不关借用检查(E0502);用 unsafe 实现带 assert 的安全 split_at_mut;#![forbid(unsafe_code)] 与 2024 edition 的 unsafe_op_in_unsafe_fn。