Previous Next

Rust 程序设计语言 简体中文版(The Rust Programming Language (2e)) (Steve Klabnik, Carol Nichols)(Z-Library)

Author: Steve Klabnik, Carol Nichols

RUST

本书的英文原版作者为 Steve Klabnik 和 Carol Nichols,并由 Rust 社区补充完善。本简体中文译本由 Rust 中文社区翻译。 本书假设你使用的是 Rust 1.90.0(2025-09-18 发布)或更高版本,并在所有项目的Cargo.toml 文件中通过 edition = "2024"将其配置为使用 Rust 2024 Edition 惯用法。请查看第一章的 “安装” 部分了解如何安装和升级 Rust,并查看附录 E 了解版本相关的信息。 本书的英文原版 HTML 格式可以在在线阅读;使用rustup 安装的 Rust 也包含一份英文离线版,运行 rustup docs --book 即可打开。 本书还有一些社区翻译版本。(译者注:简体中文译本可以在 在线阅读,PDF 版本请下载 Rust 程序设计语言 简体中文版.pdf)

📄 File Format: PDF
💾 File Size: 9.2 MB
13
Views
0
Downloads
0.00
Total Donations

📄 Text Preview (First 20 pages)

ℹ️

Registered users can read the full content for free

Register as a Gaohf Library member to read the complete e-book online for free and enjoy a better reading experience.

📄 Page 1
Rust 程序设计语言 简体中文版
📄 Page 2
Rust 程序设计语言 简体中文版 目录 Rust 程序设计语言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 前言 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 简介 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1. 入门指南 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.1. 安装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.2. Hello, World! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.3. Hello, Cargo! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2. 编写一个猜数字游戏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3. 常见编程概念 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3.1. 变量与可变性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 3.2. 数据类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.3. 函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 3.4. 注释 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57 3.5. 控制流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58 4. 认识所有权 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 4.1. 什么是所有权? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68 4.2. 引用与借用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 4.3. Slice 类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 5. 使用结构体组织相关联的数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96 5.1. 结构体的定义和实例化 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97 5.2. 结构体示例程序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103 5.3. 方法语法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109 6. 枚举和模式匹配 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 6.1. 枚举的定义 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115 6.2. match 控制流结构 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 6.3. if let 和 let else 简洁控制流 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128 7. 使用包、Crate 和模块管理不断增长的项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131 7.1. 包和 Crate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132 7.2. 定义模块来控制作用域与私有性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 7.3. 引用模块树中项的路径 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137 7.4. 使用 use 关键字将路径引入作用域 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 7.5. 将模块拆分成多个文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 8. 常见集合 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152 8.1. 使用 Vector 储存列表 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153 8.2. 使用字符串储存 UTF-8 编码的文本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 8.3. 使用 Hash Map 储存键值对 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 165 9. 错误处理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170 9.1. 用 panic! 处理不可恢复的错误 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 9.2. 用 Result 处理可恢复的错误 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174 9.3. 要不要 panic! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 184 10. 泛型、Trait 和生命周期 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188 10.1. 泛型数据类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 191 10.2. Trait:定义共同行为 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199 10.3. 生命周期确保引用有效 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207 2/562
📄 Page 3
Rust 程序设计语言 简体中文版 11. 编写自动化测试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 219 11.1. 如何编写测试 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 220 11.2. 控制测试如何运行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 236 11.3. 测试的组织结构 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 243 12. 一个 I/O 项目:构建命令行程序 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249 12.1. 接受命令行参数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 12.2. 读取文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253 12.3. 重构以改进模块化与错误处理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 12.4. 采用测试驱动开发完善库的功能 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265 12.5. 处理环境变量 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271 12.6. 将错误信息输出到标准错误而不是标准输出 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276 13. 函数式语言特性:迭代器与闭包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278 13.1. 闭包:可以捕获其环境的匿名函数 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279 13.2. 使用迭代器处理元素序列 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 13.3. 改进之前的 I/O 项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294 13.4. 性能比较:循环对迭代器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298 14. 更多关于 Cargo 和 Crates.io 的内容 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300 14.1. 采用发布配置自定义构建 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 301 14.2. 将 crate 发布到 Crates.io . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 302 14.3. Cargo 工作空间 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 14.4. 使用 cargo install 安装二进制文件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317 14.5. Cargo 自定义扩展命令 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318 15. 智能指针 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319 15.1. 使用 Box<T> 指向堆上数据 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320 15.2. 使用 Deref Trait 将智能指针当作常规引用处理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326 15.3. 使用 Drop Trait 运行清理代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331 15.4. Rc<T> 引用计数智能指针 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335 15.5. RefCell<T> 与内部可变性模式 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 339 15.6. 引用循环会导致内存泄漏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347 16. 无畏并发 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 354 16.1. 使用线程同时地运行代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355 16.2. 使用消息传递在线程间通信 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361 16.3. 共享状态并发 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367 16.4. 使用 Sync 与 Send Traits 的可扩展并发 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373 17. Async 和 await . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375 17.1. Futures 和 async 语法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378 17.2. 并发与 async . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 385 17.3. 使用任意数量的 futures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393 17.4. 流(Streams) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405 17.5. 深入理解 async 相关的 traits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414 17.6. future、任务和线程 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422 18. 面向对象编程特性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425 18.1. 面向对象语言的特征 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426 18.2. 顾及不同类型值的 trait 对象 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429 18.3. 面向对象设计模式的实现 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434 19. 模式与模式匹配 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 445 3/562
📄 Page 4
Rust 程序设计语言 简体中文版 19.1. 所有可能会用到模式的位置 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446 19.2. Refutability(可反驳性): 模式是否会匹配失效 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451 19.3. 模式语法 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 453 20. 高级特性 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 465 20.1. 不安全 Rust . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466 20.2. 高级 trait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477 20.3. 高级类型 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488 20.4. 高级函数与闭包 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494 20.5. 宏 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498 21. 最后的项目:构建多线程 web server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507 21.1. 建立单线程 web server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508 21.2. 将单线程 server 变为多线程 server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517 21.3. 优雅停机与清理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533 22. 附录 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 541 22.1. A - 关键字 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542 22.2. B - 运算符与符号 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545 22.3. C - 可派生的 trait . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 552 22.4. D - 实用开发工具 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555 22.5. E - 版本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558 22.6. F - 本书译本 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 559 22.7. G - Rust 是如何开发的与 “Nightly Rust” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 560 4/562
📄 Page 5
Rust 程序设计语言 简体中文版 Rust 程序设计语言 title-page.md 本书的英文原版作者为 Steve Klabnik 和 Carol Nichols,并由 Rust 社区补充完善。本简体 中文译本由 Rust 中文社区翻译。 本书假设你使用的是 Rust 1.90.0(2025-09-18 发布)或更高版本,并在所有项目的 Cargo.toml 文件中通过 edition = "2024"将其配置为使用 Rust 2024 Edition 惯用法。请查 看第一章的 “安装” 部分了解如何安装和升级 Rust,并查看附录 E了解版本相关的信息。 本书的英文原版 HTML 格式可以在 https://doc.rust-lang.org/stable/book/ 在线阅读;使用 rustup 安装的 Rust 也包含一份英文离线版,运行 rustup docs --book 即可打开。 本书还有一些社区 翻译版本。(译者注:简体中文译本可以在 https://kaisery.github.io/trpl- zh-cn/ 在线阅读,PDF 版本请下载 Rust 程序设计语言 简体中文版.pdf) 本书也有由 No Starch Press 出版的纸质版和电子版。 🚨 想要具有互动性的学习体验吗?试试 Rust Book 的另一个版本,其中包括测验、 高亮、可视化等功能:https://rust-book.cs.brown.edu 5/562
📄 Page 6
Rust 程序设计语言 简体中文版 前言 foreword.md Rust 程序设计语言在短短几年内走过了很长的路,从由一小群尚处起步阶段的爱好者社区创 建并孵化,到成为世界上最受喜爱、需求最旺盛的编程语言之一。回望过去,Rust 的强大与 潜力让它引人注目,并在系统编程中站稳脚跟,这几乎是不可避免的。并非理所当然的,则是 渗透于开源社区之中的全球范围内兴趣与创新的增长,并催化了产业内的大规模采用。 此时此刻,很容易指出 Rust 所必须提供的一系列出色特性,来解释它在关注度与采用率上的 激增。谁会不想要内存安全,并且 高性能,并且 友好的编译器,并且 出色的工具链,以及其 他众多优秀特性呢?你今天看到的 Rust,将系统编程领域多年的研究成果与一个充满活力、 富有热情的社区所积累的实践智慧融为一体。这门语言被有目的地设计,并被精心打磨,为开 发者提供了一种更容易编写安全、快速且可靠的代码的工具。 不过,使 Rust 真正与众不同的是它根植于赋能你——也就是用户——去实现你的目标。这是 一门希望你成功的语言,而赋能这一原则贯穿于构建、维护并倡导这门语言的社区核心。自本 书上一版以来,Rust 进一步发展为一门真正全球化且值得信赖的语言。Rust 项目(Rust Project)如今得到了 Rust 基金会(Rust Foundation)的强有力支持,该基金会也在关键倡 议上持续投入,以确保 Rust 安全、稳定且可持续。 这一版的《Rust 程序设计语言》是一次全面更新,反映了这门语言多年来的演进并提供了有 价值的新信息。但它不仅仅是一份关于语法和库的指南——更是一份邀请,欢迎你加入一个重 视质量、性能与深思熟虑设计的社区。无论你是经验丰富的开发者想第一次探索 Rust,还是 资深的 Rustacean 想进一步打磨你的技能,这一版都能为每个人提供值得收获的内容。 Rust 的历程是一段协作、学习与迭代的旅程。语言及其生态系统的成长直接反映了其背后充 满活力、丰富多元的社区。成千上万开发者的贡献——从核心语言设计者到随手贡献的参与者 ——共同造就了 Rust 这一独特且强大的工具。拿起本书,你不仅是在学习一门新的编程语言 ——你是在加入一场让软件更好、更安全、并且更令人愉快的运动。 欢迎来到 Rust 社区! • Bec Rumbul,Rust 基金会执行董事 6/562
📄 Page 7
Rust 程序设计语言 简体中文版 简介 注意:此书的英文原版与 No Starch Press 出版的《The Rust Programming Language》纸质版和电子版一致。 欢迎阅读《Rust 程序设计语言》,这是一本关于 Rust 的入门书籍。Rust 程序设计语言能帮助 你编写更快、更可靠的软件。在编程语言设计中,高层的工程学与底层的控制往往是难以兼得 的;而 Rust 则试图挑战这一矛盾。通过平衡强大的技术能力与优秀的开发者体验,Rust 为你 提供了控制底层细节(如内存使用)的选项,而无需承受通常与此类控制相关的所有繁琐细 节。 Rust 适合哪些人 Rust 因多种原因适合许多人。让我们看看几个最重要的群体。 开发者团队 Rust 已被证明是一个对于具有不同系统编程知识水平的大型开发团队协作而言,非常高效的 工具。底层代码容易出现各种微妙的错误,在大多数其他语言中,这些错误只能通过广泛的测 试和经验丰富的开发者的仔细审核代码来捕捉。在 Rust 中,编译器充当了守门员的角色,拒 绝编译包含这些难以察觉的错误的代码,包括并发错误。通过与编译器合作,团队可以将时间 集中在程序逻辑上,而不是追踪 bug。 Rust 也为系统编程世界带来了现代化的开发工具: • Cargo 是内置的依赖管理器和构建工具,它能轻松增加、编译和管理依赖,并使依赖在 Rust 生态系统中保持一致。 • Rustfmt 格式化工具确保开发者遵循一致的代码风格。 • rust-analyzer 为集成开发环境(IDE)提供了强大的代码补全和内联错误信息功能。 通过使用 Rust 生态系统中丰富的工具,开发者在编写系统级代码时可以更加高效。 学生 Rust 适合学生群体,也适合有兴趣学习系统概念的人。许多人通过 Rust 学习了操作系统开发 等主题。社区对学生问题非常欢迎并乐于回答。通过类似这本书以及其他内容的努力,Rust 团队希望使系统概念能为更多人所易于理解,特别是编程新手。 公司 数百家大小规模的公司在生产环境中使用 Rust 完成各种任务,包括命令行工具、Web 服务、 DevOps 工具、嵌入式设备、音视频分析与转码、加密货币、生物信息学、搜索引擎、物联网 (IOT)程序、机器学习,甚至是 Firefox 浏览器的重要部分。 开源开发者 Rust 适合那些希望构建 Rust 编程语言、社区、开发工具和库的开发者。我们非常欢迎你为 Rust 语言作出贡献。 7/562
📄 Page 8
Rust 程序设计语言 简体中文版 重视速度和稳定性的开发者 Rust 适合那些渴望在编程语言中寻求速度与稳定性的开发者。对于速度来说,既是指 Rust 可 以运行的多快,也是指编写 Rust 程序的速度。Rust 编译器的检查确保了增加功能和重构代码 时的稳定性,这与那些缺乏这些检查的语言中脆弱的祖传代码形成了鲜明对比,开发者往往不 敢去修改这些代码。通过追求零成本抽象(zero-cost abstractions)—— 将高级语言特性编 译成底层代码,并且与手写的代码运行速度同样快。Rust 努力确保代码又安全又快速。 这里提到的只是几个较大的受益群体,Rust 语言也希望能支持更多其他用户。总的来说, Rust 最重要的目标是消除数十年来程序员习以为常的取舍,让安全和高效、速度和易读易用 可以兼得。试试看 Rust,说不定它的选择就适合你。 本书适合哪些人 本书假设你已经有其他编程语言的经验,任何语言均可,我们力求让各种语言背景的人都能读 懂。本书的重点不是程序设计本身,也不是程序设计思维。如果你完全没学过编程,建议你先 阅读专门介绍程序设计的书籍。 如何阅读本书 本书大体上假设你按从头到尾的顺序阅读。后面的章节建立在前面章节概念的基础上。前面的 章节可能不会深入介绍部分主题,而是留待后续章节重新讨论。 本书分为两类章节:概念章节和项目章节。在概念章节中,我们学习 Rust 的某个方面。在项 目章节中,我们应用目前所学的知识一同构建小型程序。第二、十二和二十一章是项目章节; 其余都是概念章节。 第一章介绍如何安装 Rust,如何编写一个 “Hello, world!” 程序,以及如何使用 Rust 的包管理 器和构建工具 Cargo。第二章是一个编写 Rust 语言的实战介绍,我们会构建一个猜数字游戏。 我们会站在较高的层次介绍一些概念,而后续章节将提供更多细节。如果你希望立刻就动手实 践一下,第二章是开始的好地方。第三章介绍 Rust 中类似其他编程语言的特性,第四章会学 习 Rust 的所有权系统。如果你是一个特别细致的学习者,喜欢在进入下一环节之前学习每一 个细节,你可能会想要跳过第二章,直接阅读第三章,等到你想要通过项目应用所学到的细节 时再回到第二章。 第五章讨论结构体(struct)和方法,第六章介绍枚举(enum)、match 表达式和 if let 控 制流结构。在 Rust 中,创建自定义类型需要用到结构体和枚举。 第七章介绍 Rust 的模块(module)系统,其中的私有性规则用来组织代码和公开的 API(应 用程序接口)。第八章讨论标准库提供的常见集合数据结构,例如 Vector(向量)、字符串和 Hash Map(散列表)。第九章探索 Rust 的错误处理的理念与技术。 第十章深入介绍泛型(generic)、Trait 和生命周期(lifetime),这些功能让你能够定义适用 于多种类型的代码。第十一章全面讲述了测试,因为就算 Rust 有安全保证,也需要测试确保 程序逻辑正确。第十二章中将会构建我们自己的 grep 命令行工具的功能子集实现,用于在文 件中搜索文本。为此会用到之前章节讨论的很多概念。 第十三章探索闭包(closure)和迭代器(iterator),这两个 Rust 特性来自函数式编程语言。 第十四章会深入探讨 Cargo 并介绍分享代码库的最佳实践。第十五章讨论标准库提供的智能 指针以及相关的 trait。 8/562
📄 Page 9
Rust 程序设计语言 简体中文版 第十六章将引导我们了解不同的并发编程模型,并探讨 Rust 如何帮助你无畏地进行多线程编 程。第十七章将在此基础上进一步探索 Rust 的 async 和 await 语法,以及它们所支持的轻量 级并发模型。 第十八章着眼于 Rust 风格与你可能比较熟悉的 OOP(面向对象编程)原则之间的比较。第十 九章是一个模式和模式匹配的参考,它们是在 Rust 程序中表达思想的有效方式。第二十章是 一个高级主题大杂烩,包括不安全 Rust(unsafe Rust)、宏(macro)和更多关于生命周期、 Trait、类型、函数和闭包的内容。 第二十一章我们将会完成一个项目,实现一个底层多线程的 Web 服务端! 最后的附录包含了一些关于该语言的实用信息,其格式更像是参考资料。附录 A 涵盖了 Rust 的关键字,附录 B 涵盖了 Rust 的运算符和符号,附录 C 涵盖了标准库提供的可派生 trait,附 录 D 涵盖了一些有用的开发工具,而附录 E 解释了 Rust 版本。在附录 F 中,你可以找到本书 的翻译版本,而在附录 G 中,我们将讨论 Rust 是如何制作的以及什么是 nightly Rust。 阅读本书没有错误的方式:如果你想跳过前面的内容,尽管跳过!如果你遇到任何困惑,可能 需要回到前面的章节。请采取对你最有效的方式进行阅读。 学习 Rust 的一个重要部分是学会如何阅读编译器显示的错误信息:它们会指引你编写出能运 行的代码。为此,我们将提供许多不能编译的示例,以及在每种情况下编译器将显示的错误信 息。请知悉,如果你输入并运行一个随机示例,它可能无法编译!确保你阅读了示例周围的文 本,以判断你尝试运行的示例是否出错。Ferris 也将帮助你区分那些不是意在工作的代码: Ferris 含义 这段代码无法通过编译! 9/562
📄 Page 10
Rust 程序设计语言 简体中文版 这段代码会 Panic! 这段代码的运行结果不符合预期。 在大部分情况,我们会指导你将无法通过编译的代码修改为正确版本。 源代码 生成本书的源码可以在 GitHub 上找到。 译者注:此译本也有 GitHub 仓库,欢迎提交 Issue 和 PR :) 10/562
📄 Page 11
Rust 程序设计语言 简体中文版 入门指南 让我们开始 Rust 之旅!有很多内容需要学习,但每次旅程总有起点。在本章中,我们会讨论: • 在 Linux、macOS 和 Windows 上安装 Rust • 编写一个打印 Hello, world! 的程序 • 使用 Rust 的包管理器和构建系统 cargo 11/562
📄 Page 12
Rust 程序设计语言 简体中文版 安装 第一步是安装 Rust。我们会通过 rustup 下载 Rust,这是一个管理 Rust 版本和相关工具的命 令行工具。下载时需要联网。 注意:如果你出于某些理由倾向于不使用 rustup,请到 Rust 的其他安装方法页面 查 看其它安装选项。 接下来的步骤会安装最新的稳定版 Rust 编译器。Rust 的稳定性确保本书所有示例在最新版本 的 Rust 中能够继续编译。不同版本的输出可能略有不同,因为 Rust 经常改进错误信息和警 告。也就是说,任何通过这些步骤安装的最新稳定版 Rust,都应该能正常运行本书中的内容。 命令行标记 本章和全书中,我们会展示一些在终端中使用的命令。所有需要输入到终端的行都以 $ 开头。你不需要输入 $ 字符;这里显示的 $ 字符表示命令行提示符,仅用于提示每 行命令的起点。不以 $ 起始的行通常展示前一个命令的输出。另外,PowerShell 专 用的示例会采用 > 而不是 $。 在 Linux 或 macOS 上安装 rustup 如果你使用 Linux 或 macOS,打开终端并输入如下命令: $ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh 此命令下载一个脚本并开始安装 rustup 工具,这会安装最新稳定版 Rust。过程中可能会提示 你输入密码。如果安装成功,将会出现如下内容: Rust is installed now. Great! 另外,你还需要一个 链接器(linker),它是 Rust 用来将其编译的输出链接成一个文件的程 序。很可能你已经有一个了。如果你遇到了链接器错误,请尝试安装一个 C 编译器,它通常包 括一个链接器。C 编译器也很有用,因为一些常见的 Rust 包依赖于 C 代码,因此需要安装一 个 C 编译器。 在 macOS 上,你可以通过运行以下命令获得 C 语言编译器: $ xcode-select --install Linux 用户通常需要根据发行版(distribution)文档安装 GCC 或 Clang。比如,如果你使用 Ubuntu,可以安装 build-essential 包。 12/562
📄 Page 13
Rust 程序设计语言 简体中文版 在 Windows 上安装 rustup 在 Windows 上,前往 https://www.rust-lang.org/install.html 并按照说明安装 Rust。在安 装过程的某个步骤,你会被提示要安装 Visual Studio。它提供了一个链接器和编译程序所需 的原生库。如果你在此步骤需要更多帮助,请访问 https://rust-lang.github.io/rustup/ installation/windows-msvc.html。 本书的余下部分会使用能同时运行于 cmd.exe 和 PowerShell 的命令。如果存在特定差异,我 们会解释使用哪一个。 故障排除(Troubleshooting) 要检查是否正确安装了 Rust,打开命令行并输入: $ rustc --version 你应该可以看到按照以下格式显示的最新稳定版本的版本号、对应的 Commit Hash 和 Commit 日期: rustc x.y.z (abcabcabc yyyy-mm-dd) 如果看到了这样的信息,就说明 Rust 已经安装成功了!如果没看到,请按照下面说明的方法 检查 Rust 是否在您的 %PATH% 系统变量中。 在 Windows CMD 中,请使用命令: > echo %PATH% 在 PowerShell 中,请使用命令: > echo $env:Path 在 Linux 和 macOS 中,请使用命令: $ echo $PATH 如果一切正确但 Rust 仍不能使用,有许多地方可以求助。您可以在社区页面查看如何与其他 Rustaceans(Rust 用户的称号,有自嘲意味)联系。 更新与卸载 通过 rustup 安装了 Rust 之后,更新到最新版本就很简单了。只需要在您对应的命令行中运行 如下更新脚本: $ rustup update 若要卸载 Rust 和 rustup,请在命令行中运行如下卸载脚本: 13/562
📄 Page 14
Rust 程序设计语言 简体中文版 $ rustup self uninstall 本地文档 安装程序也自带一份文档的本地拷贝,可以离线阅读。运行 rustup doc 在浏览器中查看本地 文档。 任何时候,如果你拿不准标准库中的类型或函数的用途和用法,请查阅应用程序接口 (application programming interface,API)文档! 文本编辑器和集成开发环境(Integrated Development Environments, IDE) 本书不会假设你使用何种工具来编写 Rust 代码。几乎任何文本编辑器都可以搞定!然而,很 多文本编辑器和集成开发环境(IDE)内置了 Rust 支持。你总是可以在 Rust 官网的工具页面 找到很多相对流行的编辑器和 IDE 列表。 离线使用本书 在一些示例中,我们将会使用标准库之外的 Rust 包。要运行这些示例,你需要保持网络连接, 或者事先下载好这些依赖。要提前下载依赖,可以运行以下命令。(我们稍后会详细解释 cargo 是什么,以及这些命令分别的作用。) $ cargo new get-dependencies $ cd get-dependencies $ cargo add rand@0.8.5 trpl@0.2.0 这会将这些包的下载结果缓存起来,因此你之后就不需要再下载它们了。运行完该命令后,你 无需保留 get-dependencies 文件夹。一旦你运行了这些命令,就可以在本书之后所有的 cargo 命令中,使用 --offline 参数来使用这些缓存的版本,而不必尝试使用网络。 14/562
📄 Page 15
Rust 程序设计语言 简体中文版 Hello, World! 既然安装好了 Rust,是时候来编写第一个 Rust 程序了。当学习一门新语言的时候,使用该语 言在屏幕上打印 Hello, world! 是一项传统,我们将沿用这一传统! 注意:本书假设你熟悉基本的命令行操作。Rust 对于你的编辑器、工具,以及代码位 于何处并没有特定的要求,如果你更倾向于使用集成开发环境(IDE),而不是命令 行,请尽管使用你喜欢的 IDE。目前很多 IDE 都在一定程度上支持 Rust;查看 IDE 文档以了解更多细节。Rust 团队一直致力于借助 rust-analyzer 提供强大的 IDE 支 持。详见附录 D。 创建项目目录 首先创建一个存放 Rust 代码的目录。Rust 并不关心代码的存放位置,不过对于本书的练习和 项目来说,我们建议你在 home 目录中创建 projects 目录,并将你的所有项目存放在这里。 打开终端并输入如下命令创建 projects 目录,并在 projects 目录中为 “Hello, world!” 项目创建 一个目录。 对于 Linux、macOS 和 Windows PowerShell,输入: $ mkdir ~/projects $ cd ~/projects $ mkdir hello_world $ cd hello_world 对于 Windows CMD,输入: > mkdir "%USERPROFILE%\projects" > cd /d "%USERPROFILE%\projects" > mkdir hello_world > cd hello_world 编写并运行 Rust 程序 接下来,新建一个源文件,命名为 main.rs。Rust 源文件总是以 .rs 扩展名结尾。如果文件名 包含多个单词,那么按照命名习惯,应当使用下划线来分隔单词。例如命名为 hello_world.rs, 而不是 helloworld.rs。 现在打开刚创建的 main.rs 文件,输入示例 1-1 中的代码。 文件名:main.rs fn main() { println!("Hello, world!"); } 保存文件,并回到当前目录为  /projects/hello_world 的终端窗口。在 Linux 或 macOS 上,输 入如下命令,编译并运行文件: 15/562
📄 Page 16
Rust 程序设计语言 简体中文版 $ rustc main.rs $ ./main Hello, world! 在 Windows 上,输入命令 .\main.exe,而不是 ./main: > rustc main.rs > .\main Hello, world! 不管使用何种操作系统,终端应该打印字符串 Hello, world!。如果没有看到这些输出,回到 安装部分的 “故障排除” 小节查找有帮助的方法。 如果 Hello, world! 出现了,恭喜你!你已经正式编写了一个 Rust 程序。现在你成为一名 Rust 程序员,欢迎! Rust 程序的结构 现在,让我们回过头来仔细看看这个 “Hello, world!” 程序。这是第一块拼图: fn main() { } 这几行定义了一个名叫 main 的函数。main 函数是一个特殊的函数:在可执行的 Rust 程序中, 它总是最先运行的代码。第一行代码声明了一个叫做 main 的函数,它没有参数也没有返回值。 如果有参数的话,它们的名称应该出现在小括号 () 中。 函数体被包裹在 {} 中。Rust 要求所有函数体都要用花括号包裹起来。一般来说,将左花括号 与函数声明置于同一行并以空格分隔,是良好的代码风格。 注:如果你希望在 Rust 项目中保持一种标准风格,可以使用名为 rustfmt 的自动格 式化工具将代码格式化为特定的风格(更多内容详见附录 D 中的 rustfmt)。Rust 团 队已经在标准的 Rust 发行版中包含了这个工具,就像 rustc 一样。所以它应该已经 安装在你的电脑中了! 在 main 函数体中有如下代码: println!("Hello, world!"); 这行代码完成这个简单程序的所有工作:在屏幕上打印文本。这里有三个重要的细节需要注 意。 首先,println! 调用了一个 Rust 宏(macro)。如果是调用函数,则应输入 println(没有 !)。我们将在第二十章详细讨论宏。现在你只需记住,当看到符号 ! 的时候,就意味着调用 的是宏而不是普通函数,并且宏并不总是遵循与函数相同的规则。 16/562
📄 Page 17
Rust 程序设计语言 简体中文版 第二,"Hello, world!" 是一个字符串。我们把这个字符串作为一个参数传递给 println!,字 符串将被打印到屏幕上。 第三,该行以分号结尾(;),这代表一个表达式的结束和下一个表达式可以开始。大部分 Rust 代码行以分号结尾。 编译和运行是彼此独立的步骤 你刚刚运行了一个新创建的程序,那么让我们检查此过程中的每一个步骤。 在运行 Rust 程序之前,必须先使用 Rust 编译器编译它,即输入 rustc 命令并传入源文件名 称,如下: $ rustc main.rs 如果你有 C 或 C++ 背景,就会发现这与 gcc 和 clang 类似。编译成功后,Rust 会输出一个二 进制的可执行文件。 在 Linux、macOS 或 Windows 的 PowerShell 上,在 shell 中输入 ls 命令可以看见这个可 执行文件。 $ ls main main.rs 在 Linux 和 macOS,你会看到两个文件。在 Windows PowerShell 中,你会看到同使用 CMD 相同的三个文件。在 Windows 的 CMD 上,则输入如下命令: > dir /B %= the /B option says to only show the file names =% main.exe main.pdb main.rs 这展示了扩展名为 .rs 的源文件、可执行文件(在 Windows 下是 main.exe,其它平台是 main),以及当使用 CMD 时会有一个包含调试信息、扩展名为 .pdb 的文件。从这里开始运行 main 或 main.exe 文件,如下: $ ./main # Windows 是 .\main.exe 如果这里的 main.rs 是上文所述的 “Hello, world!” 程序,那么在终端上就会打印出 Hello, world!。 如果你更熟悉动态语言,如 Ruby、Python 或 JavaScript,则可能不习惯将编译和运行分为两 个单独的步骤。Rust 是一种 预编译静态类型(ahead-of-time compiled)语言,这意味着你可 以编译程序,并将可执行文件送给其他人,他们甚至不需要安装 Rust 就可以运行。如果你给 他人一个 .rb、.py 或 .js 文件,他们需要先分别安装 Ruby,Python,JavaScript 实现(运行 时环境,VM)。不过在这些语言中,只需要一句命令就可以编译和运行程序。这一切都是语言 设计上的权衡取舍。 仅仅使用 rustc 编译简单程序是没问题的,不过随着项目的增长,你可能需要管理你项目的方 方面面,并让代码易于分享。接下来,我们要介绍一个叫做 Cargo 的工具,它会帮助你编写 真实世界中的 Rust 程序。 17/562
📄 Page 18
Rust 程序设计语言 简体中文版 Hello, Cargo! Cargo 是 Rust 的构建系统和包管理器。大多数 Rustacean 们使用 Cargo 来管理他们的 Rust 项目,因为它可以为你处理很多任务,比如构建代码、下载依赖库并编译这些库。(我们把代 码所需要的库叫做 依赖(dependencies))。 最简单的 Rust 程序,比如我们刚刚编写的,没有任何依赖。如果使用 Cargo 来构建 “Hello, world!” 项目,将只会用到 Cargo 构建代码的那部分功能。在编写更复杂的 Rust 程序时,你 将添加依赖项,如果使用 Cargo 启动项目,则添加依赖项将更加容易。 由于绝大多数 Rust 项目使用 Cargo,本书接下来的部分假设你也使用 Cargo。如果使用 “安 装” 部分介绍的官方安装包的话,则自带了 Cargo。如果通过其他方式安装的话,可以在终端 输入如下命令检查是否安装了 Cargo: $ cargo --version 如果你看到了版本号,说明已安装!如果看到类似 command not found 的错误,你应该查看相 应安装文档以确定如何单独安装 Cargo。 使用 Cargo 创建项目 我们使用 Cargo 创建一个新项目,然后看看与上面的 “Hello, world!” 项目有什么不同。回到 projects 目录(或者你存放代码的目录)。接着,可在任何操作系统下运行以下命令: $ cargo new hello_cargo $ cd hello_cargo 第一行命令新建了名为 hello_cargo 的目录和项目。我们将项目命名为 hello_cargo,同时 Cargo 在一个同名目录中创建项目文件。 进入 hello_cargo 目录并列出文件。将会看到 Cargo 生成了两个文件和一个目录:一个 Cargo.toml 文件,一个 src 目录,以及位于 src 目录中的 main.rs 文件。 这也会在 hello_cargo 目录初始化了一个 git 仓库,以及一个 .gitignore 文件。如果在一个已经 存在的 git 仓库中运行 cargo new,则这些 git 相关文件则不会生成;可以通过运行 cargo new --vcs=git 来覆盖这些行为。 注意:git 是一个常用的版本控制系统(version control system,VCS)。可以通过 --vcs 参数使 cargo new 切换到其它版本控制系统(VCS),或者不使用 VCS。运行 cargo new --help 查看可用的选项。 请自行选用文本编辑器打开 Cargo.toml 文件。它应该看起来与示例 1-2 中代码类似: 文件名:Cargo.toml [package] name = "hello_cargo" version = "0.1.0" edition = "2024" 18/562
📄 Page 19
Rust 程序设计语言 简体中文版 [dependencies] 这个文件使用 TOML (Tom’s Obvious, Minimal Language) 格式,这是 Cargo 配置文件的格式。 第一行,[package],是一个片段 section 标题,表明下面的语句用来配置一个包。随着我们 在这个文件增加更多的信息,还将增加其他 section。 接下来的三行设置了 Cargo 编译程序所需的配置:项目的名称、项目的版本以及要使用的 Rust 版本。附录 E 会介绍 edition 的值。 最后一行,[dependencies],是罗列项目依赖的 section 的开始。在 Rust 中,代码包被称为 crates。这个项目并不需要其他的 crate,不过在第二章的第一个项目会用到依赖,那时会用 得上这个 section。 现在打开 src/main.rs 看看: 文件名:src/main.rs fn main() { println!("Hello, world!"); } Cargo 为你生成了一个 “Hello, world!” 程序,正如我们之前编写的示例 1-1!目前为止,我们 的项目与 Cargo 生成项目的区别是 Cargo 将代码放在 src 目录,同时项目根目录包含一个 Cargo.toml 配置文件。 Cargo 期望源文件存放在 src 目录中。项目根目录只存放 README、license 信息、配置文件 和其他跟代码无关的文件。使用 Cargo 帮助你保持项目干净整洁。一切各得其所,井井有条。 如果没有使用 Cargo 开始项目,比如我们创建的 “Hello, world!” 项目,你可以将其转换为使 用 Cargo 的项目。将项目代码移入 src 目录,并创建一个合适的 Cargo.toml 文件。一个简单 的创建 Cargo.toml 文件的方法是运行 cargo init,它会自动为你创建该文件。 构建并运行 Cargo 项目 现在让我们看看通过 Cargo 构建和运行 “Hello, world!” 程序有什么不同!在 hello_cargo 目录 下,输入下面的命令来构建项目: $ cargo build Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs 这个命令会创建一个可执行文件 target/debug/hello_cargo (在 Windows 上是 targetdebughello_cargo.exe),而不是放在目前目录下。由于默认的构建方法是调试构建 (debug build),Cargo 会将可执行文件放在名为 debug 的目录中。可以通过这个命令运行可 执行文件: $ ./target/debug/hello_cargo # 或者在 Windows 下为 .\target\debug\hello_cargo.exe Hello, world! 19/562
📄 Page 20
Rust 程序设计语言 简体中文版 如果一切顺利,终端上应该会打印出 Hello, world!。首次运行 cargo build 时,也会使 Cargo 在项目根目录创建一个新文件:Cargo.lock。这个文件记录项目依赖的实际版本。这个 项目并没有依赖,所以其内容比较少。你永远也不需要手动编辑该文件;Cargo 会为你管理 它。 我们刚刚使用 cargo build 构建了项目,并使用 ./target/debug/hello_cargo 运行了程序,也 可以使用 cargo run 在一个命令中同时编译并运行生成的可执行文件: $ cargo run Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs Running `target/debug/hello_cargo` Hello, world! 比起必须先运行 cargo build 再用可执行文件的完整路径来执行程序,使用 cargo run 更方 便,所以大多数开发者会选择 cargo run。 注意这一次并没有出现表明 Cargo 正在编译 hello_cargo 的输出。Cargo 发现文件并没有被 改变,所以它并没有重新构建,而是直接运行了二进制文件。如果修改了源文件的话,Cargo 会在运行之前重新构建项目,并会出现像这样的输出: $ cargo run Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs Running `target/debug/hello_cargo` Hello, world! Cargo 还提供了一个叫 cargo check 的命令。该命令快速检查代码确保其可以编译,但并不产 生可执行文件: $ cargo check Checking hello_cargo v0.1.0 (file:///projects/hello_cargo) Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs 为什么你会不需要可执行文件呢?通常 cargo check 要比 cargo build 快得多,因为它省略了 生成可执行文件的步骤。如果你在编写代码时持续的进行检查,cargo check 可以让你快速了 解现在的代码能不能正常通过编译!为此很多 Rustaceans 编写代码时定期运行 cargo check 确保它们可以编译。当准备好使用可执行文件时才运行 cargo build。 我们回顾下已学习的 Cargo 内容: • 可以使用 cargo new 创建项目。 • 可以使用 cargo build 构建项目。 • 可以使用 cargo run 一步构建并运行项目。 • 可以使用 cargo check 在不生成二进制文件的情况下构建项目来检查错误。 • 有别于将构建结果放在与源码相同的目录,Cargo 会将其放到 target/debug 目录。 使用 Cargo 的一个额外的优点是,不论你使用什么操作系统,其命令都是一样的。所以从现 在开始本书将不再分别为 Linux 和 macOS 以及 Windows 提供相应的命令。 20/562
The above is a preview of the first 20 pages. Register to read the complete e-book.

💝 Support Author

0.00
Total Amount (¥)
0
Donation Count

Login to support the author

Login Now

Recommended for You

Loading recommended books...
Failed to load, please try again later
Back to List