Rust权威指南

本书由Rust核心开发团队编写而成,由浅入深地探讨了Rust语言的方方面面。从学习函数、选择数据结构及绑定变量入手,逐步介绍所有权、trait、生命周期、安全保证等不错概念,模式匹配、错误处理、包管理、函数式特性、并发机制等实用工具,以及完整的项目开发实战案例。

书籍介绍

章入门指南1

安装1

在Linux或macOS环境中安装Rust2
在Windows环境中安装Rust3
更新与卸载4
常见问题4
本地文档4
Hello,World!5
创建一个文件夹5
编写并运行一个Rust程序6
对这个程序的剖析7
编译与运行是不同的步骤8
Hello,Cargo!10
使用Cargo创建一个项目10
使用Cargo构建和运行项目13
以Release模式进行构建15
学会习惯Cargo15
总结16

第2章编写一个猜数游戏17

创建一个新的项目18
处理一次猜测19
使用变量来存储值20
使用Result类型来处理可能失败的情况22
通过println!中的占位符输出对应的值24
尝试运行代码24
生成一个保密数字25
借助包来获得更多功能25
生成一个随机数28
比较猜测数字与保密数字31
使用循环来实现多次猜测35
在猜测成功时优雅地退出37
处理非法输入38
总结40

第3章通用编程概念42

变量与可变性43
变量与常量之间的不同46
隐藏47
数据类型48
标量类型49
复合类型54
函数58
函数参数60
函数体中的语句和表达式61
函数的返回值63
注释66
控制流67
if表达式67
使用循环重复执行代码72
总结78

第4章认识所有权79

什么是所有权79
所有权规则82
变量作用域82
String类型83
内存与分配84
所有权与函数91
返回值与作用域92
引用与借用94
可变引用96
悬垂引用99
引用的规则101
切片101
字符串切片104
其他类型的切片109
总结109

第5章使用结构体来组织相关联的数据111

定义并实例化结构体112
在变量名与字段名相同时使用简化版的字段初始化方法114
使用结构体更新语法根据其他实例创建新实例114
使用不需要对字段命名的元组结构体来创建不同的类型115
没有任何字段的空结构体116
一个使用结构体的示例程序118
使用元组来重构代码119
使用结构体来重构代码:增加有意义的描述信息120
通过派生trait增加实用功能121
方法124
定义方法124
带有更多参数的方法127
关联函数128
多个impl块129
总结129

第6章枚举与模式匹配130

定义枚举131
枚举值131
Option枚举及其在空值处理方面的优势136
控制流运算符match140
绑定值的模式142
匹配Option<T>143
匹配必须穷举所有的可能145
_通配符146
简单控制流iflet146
总结148

第7章使用包、单元包及模块来管理日渐复杂的项目150

包与单元包152
通过定义模块来控制作用域及私有性153
用于在模块树中指明条目的路径156
使用pub关键字来暴露路径159
使用super关键字开始构造相对路径161
将结构体或枚举声明为公共的162
用use关键字将路径导入作用域165
创建use路径时的惯用模式166
使用as关键字来提供新的名称168
使用pubuse重导出名称169
使用外部包170
使用嵌套的路径来清理众多use语句171
通配符172
将模块拆分为不同的文件172
总结174

第8章通用集合类型175

使用动态数组存储多个值176
创建动态数组176
更新动态数组177
销毁动态数组时也会销毁其中的元素177
读取动态数组中的元素178
遍历动态数组中的值181
使用枚举来存储多个类型的值181
使用字符串存储UTF-8编码的文本183
字符串是什么183
创建一个新的字符串184
更新字符串185
字符串索引188
字符串切片191
遍历字符串的方法192
字符串的确没那么简单193
在哈希映射中存储键值对193
创建一个新的哈希映射194
哈希映射与所有权195
访问哈希映射中的值196
更新哈希映射197
哈希函数199
总结200

第9章错误处理201

不可恢复错误与panic!202
使用panic!产生的回溯信息203
可恢复错误与Result207
匹配不同的错误210
失败时触发panic的快捷方式:unwrap和expect212
传播错误213
要不要使用panic!219
示例、原型和测试220
当你比编译器拥有更多信息时220
错误处理的指导原则221
创建自定义类型来进行有效性验证222
总结225

10章泛型、trait与生命周期226

通过将代码提取为函数来减少重复工作227
泛型数据类型230
在函数定义中230
在结构体定义中234
在枚举定义中236
在方法定义中237
泛型代码的性能问题239
trait:定义共享行为241
定义trait241
为类型实现trait242
默认实现245
使用trait作为参数247
返回实现了trait的类型249
使用trait约束来修复largest函数251
使用trait约束来有条件地实现方法254
使用生命周期保证引用的有效性256
使用生命周期来避免悬垂引用256
借用检查器257
函数中的泛型生命周期259
生命周期标注语法260
函数签名中的生命周期标注261
深入理解生命周期2
结构体定义中的生命周期标注266
生命周期省略267
方法定义中的生命周期标注270
静态生命周期271
同时使用泛型参数、trait约束与生命周期272
总结273

11章编写自动化测试274

如何编写测试275
测试函数的构成275
使用assert!宏检查结果280
使用assert_eq!宏和assert_ne!宏判断相等性284
添加自定义的错误提示信息287
使用should_panic检查panic289
使用Result<T,E>编写测试294
控制测试的运行方式295
并行或串行地进行测试296
显示函数输出296
只运行部分特定名称的测试299
通过显式指定来忽略某些测试301
测试的组织结构303
单元测试303
集成测试305
总结311

12章I/O项目:编写一个命令行程序312

接收命令行参数313
读取参数值314
将参数值存入变量316
读取文件317
重构代码以增强模块化程度和错误处理能力319
二进制项目的关注点分离320
修复错误处理逻辑325
从main中分离逻辑330
将代码分离为独立的代码包333
使用测试驱动开发来编写库功能335
编写一个会失败的测试336
编写可以通过测试的代码339
处理环境变量343
为不区分大小写的search函数编写一个会失败的测试343
实现search_case_insensitive函数345
将错误提示信息打印到标准错误而不是标准输出349
确认错误被写到了哪里350
将错误提示信息打印到标准错误351
总结352

13章函数式语言特性:迭代器与闭包353

闭包:能够捕获环境的匿名函数354
使用闭包来创建抽象化的程序行为354
闭包的类型推断和类型标注361
使用泛型参数和Fntrait来存储闭包363
Cacher实现的局限性367
使用闭包捕获上下文环境368
使用迭代器处理元素序列371
Iteratortrait和next方法373
消耗迭代器的方法374
生成其他迭代器的方法375
使用闭包捕获环境376
使用Iteratortrait来创建自定义迭代器378
改进I/O项目381
使用迭代器代替clone381
使用迭代器适配器让代码更加清晰385
比较循环和迭代器的性能386
总结388

14章进一步认识Cargo及crates.io390

使用发布配置来定制构建391
将包发布到crates.io上392
编写有用的文档注释393
使用pubuse来导出合适的公共API397
创建crates.io账户401
为包添加元数据401
发布到crates.io403
发布已有包的新版本404
使用cargoyank命令从cargo.io上移除版本404
Cargo工作空间405
创建工作空间405
在工作空间中创建第二个包407
使用cargoinstall从crates.io上安装可执行程序413
使用自定义命令扩展Cargo的功能414
总结414

15章智能指针415

使用Box<T>在堆上分配数据417
使用Box<T>在堆上存储数据417
使用装箱定义递归类型418
通过Dereftrait将智能指针视作常规引用423
使用解引用运算符跳转到指针指向的值424
把Box<T>当成引用来操作425
定义我们自己的智能指针426
通过实现Dereftrait来将类型视作引用427
函数和方法的隐式解引用转换428
解引用转换与可变性430
借助Droptrait在清理时运行代码431
使用std::mem::drop提前丢弃值433
基于引用计数的智能指针Rc<T>435
使用Rc<T>共享数据436
克隆Rc<T>会增加引用计数439
RefCell<T>和内部可变性模式440
使用RefCell<T>在运行时检查借用规则441
内部可变性:可变地借用一个不可变的值442
将Rc<T>和RefCell<T>结合使用来实现一个拥有多重所有权的可变数据450
循环引用会造成内存泄漏452
创建循环引用453
使用Weak<T>代替Rc<T>来避免循环引用456
总结463

16章无畏并发4

使用线程同时运行代码466
使用spawn创建新线程467
使用join句柄等待所有线程结束469
在线程中使用move闭包471
使用消息传递在线程间转移数据475
通道和所有权转移478
发送多个值并观察接收者的等待过程480
通过克隆发送者创建多个生产者481
共享状态的并发483
互斥体一次只允许一个线程访问数据484
RefCell<T>/Rc<T>和tex<T>/Arc<T>之间的相似性493
使用Synctrait和Sendtrait对并发进行扩展494
允许线程间转移所有权的Sendtrait494
允许多线程同时访问的Synctrait495
手动实现Send和Sync是不安全的495
总结495

17章Rust的面向对象编程特性497

面向对象语言的特性497
对象包含数据和行为498
封装实现细节498
作为类型系统和代码共享机制的继承500
使用trait对象来存储不同类型的值502
为共有行为定义一个trait503
实现trait505
trait对象会执行动态派发509
trait对象必须保证对象安全510
实现一种面向对象的设计模式511
定义t并新建一个处于草稿状态下的新实例513
存储文章内容的文本514
确保草稿的可读内容为空515
请求审批文章并改变其状态516
添加approve方法来改变content的行为518
状态模式的权衡取舍521
总结527

18章模式匹配529

所有可以使用模式的场合530
match分支530
iflet条件表达式531
whilelet条件循环533
for循环533
let语句534
函数的参数536
可失败性:模式是否会匹配失败537
模式语法539
匹配字面量539
匹配命名变量540
多重模式541
使用...来匹配值区间542
使用解构来分解值543
忽略模式中的值548
使用匹配守卫添加额外条件554
@绑定556
总结557

19章不错特性559

不安全Rust560
不安全能力561
解引用裸指针562
调用不安全函数或方法5
访问或修改一个可变静态变量570
实现不安全trait572
使用不安全代码的时机573
不错trait573
在trait的定义中使用关联类型指定占位类型573
默认泛型参数和运算符重载575
用于消除歧义的完全限定语法:调用相同名称的方法578
用于在trait中附带另外一个trait功能的trait582
使用newtype模式在外部类型上实现外部trait585
不错类型586
使用newtype模式实现类型安全与抽象587
使用类型别名创建同义类型587
返回的Never类型590
动态大小类型和Sizedtrait593
不错函数与闭包595
函数指针595
返回闭包598
宏599
宏与函数之间的差别599
用于通用元编程的macro_rules!声明宏600
基于属性创建代码的过程宏603
如何编写一个自定义derive宏604
属性宏611
函数宏611
总结612

第20章后的项目:构建多线程Web服务器613

构建单线程Web服务器614
TCP连接615
读取请求617
仔细观察HTTP请求620
编写响应621
返回真正的HTML622
验证请求有效性并选择性地响应624
少许重构626
把单线程服务器修改为多线程服务器628
在现有的服务器实现中模拟一个慢请求628
使用线程池改进吞吐量629
优雅地停机与清理652
为ThreadPool实现Droptrait652
通知线程停止任务655
总结661
附录A关键字662
当前正在使用的关键字662
将来可能会使用的保留关键字6
原始标识符665
附录B运算符和符号667
运算符667
非运算符符号669
附录C可派生trait673
面向程序员格式化输出的Debug674
用于相等性比较的PartialEq和Eq675
使用PartialOrd和Ord进行次序比较675
使用Clone和Copy复制值676
用于将值映射到另外一个长度固定的值的Hash677
用于提供默认值的Default678
附录D有用的开发工具679
使用rustfmt自动格式化代码679
使用rustfix修复代码680
使用Clippy完成更多的代码分析681
使用Rust语言服务器来集成IDE683
附录E版本68

点赞(0) 打赏

立即下载

请先登录

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部