本书涵盖了不同境环和体系架构设计下配置Rust的技巧,并提供了解决实际问题的方案。首先介绍了Rust的核心概念,使读者能创建高效、高性能的应用,其中会使用各种Rust特性,如零成本抽象和改进内存管理。本书还介绍了更高级的主题(包括通道和actor),能构建可伸缩的生产级别的应用,还会学习错误处理、宏和模块化来编写可维护的代码。
前言
许多年前,就像很多程序员一样,我开始每年学习一种新的编程语言。通过学习另一个编程语言,可以了解很多范式和规则,并得到一些想法,然后我发现了Rust。一开始写Rust代码就非常有趣,让人无法挪步,而且经过一个陡峭的学习曲线后,它变得越发有趣。所以,总共学习了两个额外的语言后(TypeScript和Rust),我坚定地选择了Rust。为什么? 下面来告诉你原因。
Rust是一个系统编程语言,会默认地提供内存安全性而无需垃圾回收器,这会影响其运行时行为。尽管如此,Rust是一个相当全能的语言,可以在不同领域中使用,不论是Web编程、游戏引擎还是Web客户端,都可以使用Rust。另外,它对有关作用域和内存分配的传统思维发出挑战,会让你成为一个可以驾驭任何语言的更好的程序员,无论是C#、Java还是Python。Amazon、Microsoft和Google等公司的最新动向表明,这个生态系统现在已经发展到相当稳定的程度,已经足以让企业安心使用,这对未来的Rust专业人员来说是一个很好的信号。
在这本书中,我们汇编了最有用的实验,提供了实用的用例,使你能快速在生产环境中使用。我们努力涵盖了各种不同的应用,希望你能从中找到有用的概念,以及可以直接用于日常开发工作的解决方案。
本书面向对象
这本书与学习编程语言通常使用的书有所不同。这里没有很深入地探究概念,我们希望展示各种可能的项目、解决方案和应用,提供进一步的概念和其他资源的链接。所以,我们认为这本书很适合那些想要快速开发实用应用的人,而无论他们有多少Rust经验。不过,编程基础还是必要的(无论哪种语言),这是建立Rust技能的基础。
本书内容
第1章 Rust入门,介绍如何在你的计算机上建立Rust工具链,以及Rust语言的基本构造。这包括为循环、if表达式、trait(特征)和struct(结构体)等语言构造编写测试和基准测试。
第2章 高级Rust进阶,将回答有关这个语言更高级特性的问题,并介绍创建实用程序的模式。这一章的内容包括复杂场景中的借用和所有权、Option类型、模式匹配、泛型、显式生命周期和enum (枚举)。
第3章 用cargo管理项目,使用cargo工具管理额外的crate、扩展、项目和测试。你会在这里找到有关技巧,可以帮助你处理更大的项目,并解决管理这些项目时面对的挑战。
第4章 无畏并发, 这一章会介绍一些最佳实践和技巧来构建安全、快速的程序。除此以外,还会介绍诸如Rayon等流行的库,我们会展示Rust是完成各种并发任务的一个非常好的语言。
第5章 处理错误和其他结果, 解释Rust如何使用Result类型和panic (恐慌)来完成错误处理,将大部分失败用例集成到需要处理的一个常规工作流中。这一章将关于如何避免意外崩溃和不必要的复杂性为你展示一些实用的模式和最佳实践。
第6章 用宏表达,将解释Rust特有的宏系统如何在编译之前扩展程序的功能(而且会采用一种类型安全的方式)。可以为很多可能的自定义场景实现这些宏,很多crate都使用了这个功能。这一章就是要介绍如何创建有用的宏,使你的生活更轻松,也让你的程序更安全。
第7章 Rust与其他语言集成,会介绍如何在Rust中使用和处理不同的二进制单元和语言,来移植遗留软件,或者从更好的SDK获益。这主要通过外部函数接口ForeignFunctionInterface,FFI)实现,它支持与其他原生库快速而容易地集成。不仅如此,还可以使用WebAssembly从Rust发布到npm (Node.js包存储库)。所有这些内容都会在这一章讨论。
第8章 Web安全编程,使用一个先进的Web框架(actix-Web)介绍Web编程的基础知识,它展示了一种基于actor的方法来处理请求,这个Web框架在Microsoft得到了有效使用。
第9章 简化系统编程,解释Rust为什么是在资源有限的小设备上运行工作负载的一个很好的选择。具体地,由于没有垃圾回收器和相应的可预测运行时环境,这使它非常适合运行传感器数据收集器。这一章将介绍创建这样一个循环并结合必要的驱动器来读取数据。
第10章 Rust实战,介绍Rust编程中的实际问题,如解析命令行参数、使用神经网络(使用PyTorch的C++ API实现机器学习)、搜索、正则表达式、Web请求等。
目录
序
前言
第1章 Rust入门 1
1.1 建立环境 1
1.1.1 准备工作 2
1.1.2 实现过程 2
1.1.3 工作原理 4
1.2 使用命令行I/O 4
1.2.1 实现过程 4
1.2.2 工作原理 6
1.3 创建和使用数据类型 7
1.3.1 实现过程 7
1.3.2 工作原理 11
1.4 控制执行流 12
1.4.1 实现过程 12
1.4.2 工作原理 15
1.5 用crate和模块划分代码 16
1.5.1 准备工作 16
1.5.2 实现过程 16
1.5.3 工作原理 21
1.6 编写测试和基准测试 22
1.6.1 准备工作 22
1.6.2 实现过程 22
1.6.3 工作原理 27
1.7 为代码提供文档 28
1.7.1 准备工作 29
1.7.2 实现过程 29
1.7.3 工作原理 32
1.8 测试你的文档 33
1.8.1 准备工作 33
1.8.2 实现过程 33
1.8.3 工作原理 37
1.9 在类型间共享代码 38
1.9.1 实现过程 38
1.9.2 工作原理 42
1.10 Rust中的序列类型 43
1.10.1 实现过程 44
1.10.2 工作原理 46
1.11 调试Rust 47
1.11.1 准备工作 47
1.11.2 实现过程 47
1.11.3 工作原理 50
第2章 高级Rust进阶 52
2.1 用枚举创建有意义的数 52
2.1.1 实现过程 52
2.1.2 工作原理 56
2.2 没有null 57
2.2.1 实现过程 57
2.2.2 工作原理 60
2.3 使用模式匹配的复杂条件 60
2.3.1 实现过程 61
2.3.2 工作原理 66
2.4 实现自定义迭代器 67
2.4.1 准备工作 67
2.4.2 实现过程 67
2.4.3 工作原理 70
2.5 高效地过滤和转换序列 71
2.5.1 准备工作 71
2.5.2 实现过程 71
2.5.3 工作原理 74
2.6 以unsafe方式读取内存 75
2.6.1 实现过程 75
2.6.2 工作原理 77
2.7 共享所有权 78
2.7.1 准备工作 78
2.7.2 实现过程 79
2.7.3 工作原理 82
2.8 共享可变所有权 82
2.8.1 准备工作 83
2.8.2 实现过程 83
2.8.3 工作原理 87
2.9 有显式生命周期的引用 88
2.9.1 实现过程 88
2.9.2 工作原理 94
2.10 用trait绑定强制行为 94
2.10.1 实现过程 94
2.10.2 工作原理 97
2.11 使用泛型数据类型 97
2.11.1 实现过程 97
2.11.2 工作原理 102
第3章 用Cargo管理项目 104
3.1 利用工作空间组织大型项目 105
3.1.1 实现过程 105
3.1.2 工作原理 108
3.2 上传到crates.io 110
3.2.1 准备工作 110
3.2.2 实现过程 110
3.2.3 工作原理 115
3.3 使用依赖和外部crate 116
3.3.1 实现过程 116
3.3.2 工作原理 120
3.3.3 参考资料 121
3.4 用子命令扩展cargo 121
3.4.1 准备工作 122
3.4.2 实现过程 122
3.4.3 工作原理 122
3.5 用cargo测试你的项目 123
3.5.1 实现过程 123
3.5.2 工作原理 127
3.6 使用cargo持续集成 128
3.6.1 准备工作 128
3.6.2 实现过程 128
3.6.3 工作原理 131
3.7 定制构建 132
3.7.1 实现过程 132
3.7.2 工作原理 134
第4章 无畏并发 136
4.1 将数据移入线程 136
4.1.1 实现过程 137
4.1.2 工作原理 140
4.2 管理多个线程 141
4.2.1 实现过程 141
4.2.2 工作原理 142
4.3 使用通道在线程间通信 143
4.3.1 实现过程 143
4.3.2 工作原理 146
4.4 共享可变状态 146
4.4.1 实现过程 146
4.4.2 工作原理 148
4.5 Rust中的多进程 149
4.5.1 实现过程 149
4.5.2 工作原理 152
4.6 使顺序代码变为并行 152
4.6.1 实现过程 152
4.6.2 工作原理 158
4.7 向量中的并发数据处理 158
4.7.1 实现过程 159
4.7.2 工作原理 166
4.8 共享不可变状态 166
4.8.1 实现过程 167
4.8.2 工作原理 171
4.9 使用actor处理异步消息 171
4.9.1 实现过程 171
4.9.2 工作原理 174
4.10 使用future的异步编程 175
4.10.1 实现过程 175
4.10.2 工作原理 176
第5章 处理错误和其他结果 178
5.1 负责任地恐慌 178
5.1.1 实现过程 178
5.1.2 工作原理 181
5.2 处理多个错误 182
5.2.1 实现过程 182
5.2.2 工作原理 184
5.3 处理异常结果 185
5.3.1 实现过程 185
5.3.2 工作原理 188
5.4 无缝的错误处理 188
5.4.1 实现过程 188
5.4.2 工作原理 190
5.5 定制错误 191
5.5.1 实现过程 191
5.5.2 工作原理 193
5.6 弹性编程 193
5.6.1 实现过程 193
5.6.2 工作原理 194
5.7 使用外部crate来完成错误处理 194
5.7.1 实现过程 195
5.7.2 工作原理 196
5.8 Option和Result间转移 197
5.8.1 实现过程 197
5.8.2 工作原理 199
第6章 用宏表达 200
6.1 在Rust中构建自定义宏 200
6.1.1 实现过程 201
6.1.2 工作原理 202
6.2 用宏实现匹配 203
6.2.1 实现过程 203
6.2.2 工作原理 205
6.3 使用预定义的宏 206
6.3.1 实现过程 206
6.3.2 工作原理 208
6.4 使用宏生成代码 209
6.4.1 实现过程 209
6.4.2 工作原理 212
6.5 宏重载 213
6.5.1 实现过程 213
6.5.2 工作原理 216
6.6 为参数范围使用重复 216
6.6.1 实现过程 217
6.6.2 工作原理 219
6.7 不要自我重复 219
6.7.1 实现过程 220
6.7.2 工作原理 222
第7章 与其他语言集成 223
7.1 包含遗留C代码 223
7.1.1 准备工作 224
7.1.2 实现过程 225
7.1.3 工作原理 229
7.2 从Node.js使用FFI调用Rust 231
7.2.1 准备工作 231
7.2.2 实现过程 232
7.2.3 工作原理 235
7.3 在浏览器中运行Rust 236
7.3.1 准备工作 236
7.3.2 实现过程 237
7.3.3 工作原理 241
7.4 使用Rust和Python 242
7.4.1 准备工作 242
7.4.2 实现过程 243
7.4.3 工作原理 249
7.5 为遗留应用生成绑定 250
7.5.1 准备工作 250
7.5.2 实现过程 251
7.5.3 工作原理 255
第8章 Web安全编程 256
8.1 建立 Web服务器 256
8.1.1 准备工作 257