用真实编译与汇编验证 const 与 static:static 有固定的数据段地址;const fn 在编译期求值(fib(20) 变成 mov w0, #6765);static mut 访问报 E0133,2024 edition 对其取引用还触发 deny 级 lint;原子类型是安全的可变全局,static Cell 因不是 Sync 报 E0277。
用真实编译验证模块与可见性:默认私有,访问私有字段/函数报 E0616/E0603;pub(crate)、pub(super) 的范围;子模块能访问祖先的私有项而祖先不能访问子模块的;mod foo; 对应 foo.rs 或 foo/mod.rs,缺文件报 E0583。
用真实 cargo 运行验证 crate、package、workspace 的关系:同一 package 里 lib 与 bin 是两个 crate(两次 rustc 调用);workspace 共用根目录的 Cargo.lock 与 target;成员目录里 cargo 命令仍作用于整个 workspace;包名的连字符在代码里变下划线。
用真实编译与运行验证 Move 语义:赋值与传参都移动所有权,再用报 E0382(含「value moved here」等三处标注与 clone 建议);移动只拷贝 String 的 24 字节、堆数据地址不变而 clone 得到新缓冲区;循环里移动;部分移动与 drop 的归属。
用真实编译与计时验证 Copy:对 21 种类型逐个判断是否 Copy(标量、&T、元组、数组、函数指针是;String、Vec、Box、Rc、&mut、Cell、Range 不是);derive(Copy) 必须带 Clone(E0277)、与 Drop 互斥(E0184);按位复制的成本随大小增长([u8;16] 约 1 ns,1 MiB 约 21 µs)。
用真实编译验证借用检查器如何阻止悬垂引用:返回局部变量的引用(E0106、E0515)、引用比值活得久(E0597)、持有 Vec 元素引用时 push(E0502);并用裸指针观察 push 重新分配后元素地址确实变了(cap 3→6)。
用真实编译验证借用的基本规则:&T 只读、&mut T 可写,通过 & 修改报 E0594;同一时刻要么多个 &T 要么一个 &mut T(E0502、E0499);借用到最后一次使用为止;传给函数时 &mut 自动重借用,显式赋值则是移动(E0382)。
用真实编译与运行验证为什么多个不可变借用可以共存:多个 &T 指向同一份数据且 &T 是 Copy;4 个线程用 thread::scope 并发只读同一个 Vec 结果正确;&Cell 跨线程被 Sync 拒绝(E0277);读者在场时写者被拒绝(E0502)。
用真实编译与汇编验证可变借用为什么必须独占:迭代时 push 报 E0502(C++ 的迭代器失效在 Rust 里是编译错误);两个重叠的 &mut 报 E0499、split_at_mut 提供不相交的两个 &mut;&mut 版本函数直接返回常量 1 而裸指针版本要重新读内存;&mut 不是 Copy。
用真实编译验证 NLL:借用只持续到最后一次使用(旧规则会拒绝的代码被接受);借用按控制流路径存活;两阶段借用使 v.push(v.len()) 合法而保存 &mut 后读 v 则 E0502;有 Drop 的持有者让借用延续到 drop(E0499),缩小作用域修复;用 -Z dump-mir 看 NLL 的区域是 MIR 位置的集合。
用真实编译验证生命周期标注描述的是什么:两个输入引用时不标注报 E0106;<'a> 声明「返回值有效期不超过较短的输入」而不改变任何值的寿命(返回值在 b 之后使用报 E0597);不同的生命周期参数与 'b: 'a 的提示;标注与否机器码相同。
用真实编译验证函数返回引用的各种情形:单个输入引用时自动借自它(提前 drop 被借值报 E0505);方法里返回值借自 &self、其它参数先死无妨;返回指向局部变量或按值参数的引用报 E0515;返回借自集合的引用,集合先死报 E0597;返回 'static 字面量。