第1章 新时代的语言从Rust缘起、内存安全、零成本抽象和实用主义出发,追踪源码到产物的执行链,并建立采用Rust的工程判断。从系统语言的两难开始 传统系统语言给程序员直接内存控制,却把悬垂指针、重复释放和数据竞争留到运行期;托管语言用运行时回收降低内存管理负担,却引入停顿、对象布局和资源释放时序方面的约束。Rust缘起于一个更具体的问题:能否让编译器验证资源访问规则,同时保留原生代码的布局和性能控制?是可检查条件,不是“程序不会崩溃”的泛称。 设计哲学一:内存安全前移到编译期 所有权把释放责任绑定到值,借用把临时访问变成受约束的引用,生命周期描述引用不能越过被引用值。编译器拒绝无法证明安全的路径,开发者再通过重新设计owner、缩短借用、复制小值或在明确契约下使用unsafe解决。提高的是失败确定性:同一源码在部署前就暴露问题。 fn first_word(text: &str) -> &str { text.split_whitespace().next().unwrap_or("") } let owned = String::from("safe systems"); let word = first_word(&owned); assert_eq!(word, "safe"); 返回引用与输入关联,局部owned活着时才可使用word。这不证明分词符合所有语言规则,却证明引用不会指向已释放的String缓冲区。 设计哲学二:零成本抽象 通过泛型单态化、内联、枚举布局优化和迭代器融合落地。它不是“所有抽象都零指令”:分配、动态分派、引用计数和边界检查仍有成本;关键是成本可见,并且高层表达不会被迫引入不需要的运行时。 let total: i64 = (0..1_000) .map(|n| n * 2) .filter(|n| n % 3 == 0) .sum(); assert_eq!(total, 333_666); 验证零成本不能只看源码,应在release profile比较基准和汇编,并确认没有把I/O、allocator噪声或debug优化级别混入结论。 设计哲学三:实用主义 Rust没有追求纯粹的单一范式。它同时提供表达式、可变绑定、结构体、枚举、Trait、闭包、迭代器、线程、async和unsafe。意味着可以在安全外壳中保留很小的unsafe核心,也可以在并行计算中用Rayon而非手写调度器。 Rust的编译和执行 cargo run看似一步,实际包含依赖解析、crate graph构建、宏展开、名称解析、类型检查、借用检查、MIR优化、LLVM代码生成、链接与进程启动。帮助判断错误归属:过程宏panic发生在编译期,undefined reference发生在链接期,文件不存在发生在运行期。 fn main() { println!("target={} profile=release? {}", std::env::consts::ARCH, !cfg!(debug_assertions)); } 语言现状、未来与采用判断 语言现状与未来应从edition、稳定发布、目标平台、核心库、包生态和团队能力判断,而不是从热度推断。至少记录rustc -Vv、cargo -V、target、profile、lockfile和feature。采用Rust的收益通常在长寿命系统组件、并发服务、CLI和安全边界上明显;原型、生态强依赖或团队没有维护能力时,也可能不是当前最优解。 本章回顾 Rust以编译期证明换取更早失败,以零成本抽象保留系统性能,以实用主义连接生态与外部代码。判断Rust程序必须区分编译、链接和运行阶段,并保存toolchain provenance。语言选择最终服务于明确的资源、并发、互操作和维护约束。 术语表← 上一章《Rust编程之道》学习地图下一章 →第2章 语言精要讨论评论区加载中…