19
常见坑与面试重点
Pitfalls & Interview Cheat Sheet
这些坑每个新手都会踩,提前列出来,省得一个个去编译器那里挨骂。
坑 1:move 后再用原变量
let s2 = s1;(String)之后 s1 就失效了。想继续用?.clone() 深拷贝,或传 &s1 引用。编译器报 use of moved value。
坑 2:同时有可变和不可变引用
let r1=&x; let r2=&mut x; 直接编译错误。记住:同一时刻要么一个可变、要么多个不可变。
坑 3:字符串处理
String vs &str 别混;不能按索引取字符(UTF-8);遍历用 .chars();函数参数优先 &str。
坑 4:递归类型忘 Box
定义链表 enum Node { Next(Box<Node>) },不包 Box 编译器报"无限大小"。
坑 5:跨线程传非 Send
Rc 不是 Send,跨线程传编译错。多线程共享用 Arc<Mutex<T>>。
坑 6:unwrap() 滥用
生产里 .unwrap() 遇到 Err 直接 panic 崩进程。改用 ? 或 match。
高频面试题速览
展开 20 道高频面试题(含要点)
- Rust 怎么做到内存安全又没 GC? 所有权 + 借用在编译期保证,运行时零回收。
- 所有权三条规则? 单一所有者;作用域结束 drop;同时一个所有者。
- Move 和 Copy 的区别? Move 旧变量失效;Copy 是栈上简单类型自动真拷贝。
- 借用规则? 一个可变 或 多个不可变;引用必须有效。
- String 和 &str 区别? 拥有 vs 借用;参数优先 &str。
- 生命周期什么时候要手写? 返回引用且来自多个参数时。
- Option 和 Result 各自解决什么? Option 消灭 null;Result 表达可恢复错误。
- ? 运算符干了啥? 错误自动传播 + From 类型转换。
- thiserror 和 anyhow 区别? 前者库定义精确错误,后者二进制灵活兜底。
- 泛型怎么零成本? 单态化编译期展开成具体类型代码。
- Trait 和 Java 接口区别? 可有默认实现;有孤儿规则;能 dyn 动态分发。
- Box/Rc/Arc/RefCell 各干嘛? 堆分配;单线程多所有者;多线程多所有者;运行时借用检查。
- Rc 循环引用怎么破? Weak 弱引用。
- Send 和 Sync? 能否安全跨线程转移/共享,自动实现的标记 trait。
- 多线程共享可变数据标准写法? Arc<Mutex<T>>。
- 迭代器为什么快? 内联展开,零成本。
- unsafe 能做什么? 五件事:解裸指针/调unsafe fn/改static mut/实现unsafe trait/访问union。
- newtype 模式干嘛? 类型安全 + 封装 + 绕孤儿规则。
- cargo 常用命令? run/check/build/test/fmt/clippy/tree/doc。
- 2024 edition 新东西? let-else、if-let chains、async fn in trait。