首页>参考读物>计算机科学与技术>软件与程序设计

深入浅出Rust
作者 : 范长春 著
出版日期 : 2018-08-17
ISBN : 978-7-111-60642-0
定价 : 89.00元
扩展资源下载
扩展信息
语种 : 简体中文
页数 : 403
开本 : 16
原书名 :
原出版社:
属性分类: 店面
包含CD : 无CD
绝版 : 未绝版
图书简介

内容简介
本书详细描述了Rust语言的基本语法,穿插讲解一部分高级使用技巧,并以更容易理解的方式解释其背后的设计思想。全书总共分五个部分。
第一部分介绍Rust基本语法,因为对任何程序设计语言来说,语法都是基础,学习这部分是理解其他部分的前提。
第二部分介绍属于Rust独一无二的内存管理方式。它设计了一组全新的机制,既保证了安全性,又保持了强大的内存布局控制力,而且没有额外性能损失。这部分是本书的重点和核心所在,也是Rust语言的思想内核精髓之处。
第三部分介绍Rust的抽象表达能力。它支持多种编程范式,以及较为强大的抽象表达能力。
第四部分介绍并发模型。在目前这个阶段,对并行编程的支持是新一代编程语言不可绕过的重要话题。Rust也吸收了业界最新的发展成果,对并发有良好支持。
第五部分介绍一些实用设施。Rust语言有许多创新,但它绝不是高高在上孤芳自赏的类型,设计者在设计过程中充分考虑了语言的工程实用性。众多在其他语言中被证明过的优秀实践被吸收了进来,有利于提升实际工作效率。
通过此书,读者能够深入透彻地理解Rust的高阶特性,比如代数类型系统、生命周期、借用检查、内部可变性、线程安全、泛型、闭包、迭代器、生成器等。可作为参考书供学生、软件工程师、研究人员以及其他对Rust语言感兴趣的读者参考。本书所揭示的Rust编程语言的设计思想对于理解其他系统编程语言,如C++,也非常有帮助。

图书特色

本书使用通俗易懂的语言,辅以大量的代码示例,高屋建瓴地总结阐释了Rust的主要概念以及使用方法,并对背后的设计思路和原理做了深入浅出的剖析,全面深入地提炼了Rust的设计精华。

图书前言

A language that doesn’t affect the way you think about programming is not worth knowing.
——Alan Perlis
Rust简介
Rust是一门新的编程语言。
我想,大部分读者看到本书,估计都会不约而同地想到同样的问题:现存的编程语言已经多得数不清了,再发明一种新的编程语言有何意义?难道现存的那么多编程语言还不够用吗,发明一种新的编程语言能解决什么新问题?
俗话说,工欲善其事,必先利其器。在程序员平时最常用的工具排行榜中,编程语言当仁不让的是最重要的“器”。编程语言不仅是给程序设计者使用的工具,反过来,它也深刻地影响了设计者本身的思维方式和开发习惯。
卓越的编程语言,可以将优秀的设计、先进的思想、成功的经验,自然而然地融入其中,使更多的使用者开阔眼界、拓展思路,受益无穷。
A programming language is a tool that has profound influence on our thinking habits.
——Edsger Dijkstra
所以说关于这个问题,我认为,如果与现有的各种语言相比,新设计的语言有所进步、有所发展、有所创新,那么它的出现就很有意义。
最近这些年,的确涌现出了一大批编程语言,可以说是百花争艳、繁华似锦。但是在表面的繁荣之下,我们是否可以自满地说,编程语言的设计和发展已经基本成熟、趋于完美了呢?恐怕不尽然吧!
那些优秀的编程语言中,不少都有自己的“绝活”。有的性能非常高,有的表达力非常强,有的擅长组织大型程序,有的适合小巧的脚本,有的专注于并发,有的偏重于科学计算,等等,不一而足。即便如此,新兴的Rust语言面市后依旧展现出了它的独特魅力,矫矫不群,非常值得大家关注。
作为多年来鲜有的新一代系统编程语言,它的设计准则是“安全,并发,实用”。Rust的设计者是这样定位这门语言的:
Rust is a system’s programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety.
安全
是的,安全性很重要。Rust最重要的特点就是可以提供内存安全保证,而且没有额外的性能损失。
在传统的系统级编程语言(C/C++)的开发过程中,经常出现因各种内存错误引起的崩溃或bug。比如空指针、野指针、内存泄漏、内存越界、段错误、数据竞争、迭代器失效等,血泪斑斑,数不胜数。这些问题不仅在教科书中被无数次提起,而且在实践中也极其常见。因此,各种高手辛苦地总结了大量的编程经验,许多代码检查和调试工具被开发出来,各种代码开发流程和规范被制定出来,无数人呕心沥血就是为了系统性地防止各类bug的出现。尽管如此,我们依然无法彻底解决这些问题。
教科书解决不了问题,因为教育不是强制性的;静态代码检查工具解决不了问题,因为传统的C/C++对静态代码检查不友好,永远只能查出一部分问题;软件工程解决不了问题,因为规范依赖于执行者的素质,任何人都会犯错误。事后debug也不是办法,解决bug的代价更高。
鉴于手动内存管理非常容易出问题,因此先辈们发明了一种自动垃圾回收的机制(Garbage Collection),故而程序员在绝大多数情况下不用再操心内存释放的问题。新发明的绝大多数编程语言都使用了基于各种高级算法的自动垃圾回收机制,因为它确实方便,解放了程序员的大脑,使大家能更专注于业务逻辑的部分。但是到目前为止,不管使用哪种算法的GC系统,在性能上都要付出比较大的代价。要么需要较大的运行时占用较大内存,要么需要暂停整个程序,要么具备不确定性的时延。当然,在现实的许多业务场景中,这点开销是微不足道的,因此问题不大。可是如果在性能敏感的领域,这是完全不可接受的。
很遗憾,到目前为止,在系统级编程语言中,我们依然被各种内存安全问题所困扰。这些年来,许多新的语言特性被发明出来,许多优秀的编程范式被总结出来,许多高质量的代码库被开发出来。但是内存安全问题依然像一个幽灵一样,一直徘徊在众多程序员的头顶,无法摆脱。再多的努力,也只能减少它出现的机会,很难保证完整地解决掉这一类错误。
Rust对自己的定位是接近芯片硬件的系统级编程语言,因此,它不可能选择使用自动垃圾回收的机制来解决问题。事实证明,要想解决内存安全问题,小修小补是不够的,必须搞清楚导致内存错误的根本原因,从源头上解决。Rust就是为此而生的。Rust语言是可以保证内存安全的系统级编程语言。这是它的独特的优势。本书将用大量的篇幅详细介绍“内存安全”。
并发
在计算机单核性能越来越接近瓶颈的今天,多核并行成了提高软件执行效率的发展趋势。一些编程语言已经开始从语言层面支持并发编程,把“并发”的概念植入到了编程语言的血液中。然而,在传统的系统级编程语言中,并行代码很容易出错,而且有些问题很难复现,难以发现和解决问题,debug的成本非常高。线程安全问题一直以来都是非常令人头痛的问题。
Rust当然也不会在这一重要领域落伍,它也非常好地支持了并发编程。更重要的是,在强大的内存安全特性的支持下,Rust一举解决了并发条件下的数据竞争(Data Race)问题。它从编译阶段就将数据竞争解决在了萌芽状态,保障了线程安全。
Rust在并发方面还具有相当不错的可扩展性。所有跟线程安全相关的特性,都不是在编译器中写死的。用户可以用库的形式实现各种高效且安全的并发编程模型,进而充分利用多核时代的硬件性能。
实用
Rust并不只是实验室中的研究型产品,它的目标是解决目前软件行业中实实在在的各种问题。它的实用性体现在方方面面。
Rust编译器的后端是基于著名的LLVM完成机器码生成和优化的,它只需要一个非常小巧的运行时即可工作,执行效率上可与C语言相媲美,具备很好的跨平台特性。
Rust摈弃了手动内存管理带来的各种不安全的弊端,同时也避免了自动垃圾回收带来的效率损失和不可控性。在绝大部分情况下,保持了“无额外性能损失”的抽象能力。
Rust具备比较强大的类型系统,借鉴了许多现代编程语言的历史经验,包含了众多方便的语法特性。其中包括代数类型系统、模式匹配、闭包、生成器、类型推断、泛型、与C库ABI兼容、宏、模块管理机制、内置开源库发布和管理机制、支持多种编程范式等。它吸收了许多其他语言中优秀的抽象能力,海纳百川,兼容并蓄。在不影响安全和效率的情况下,拥有不俗的抽象表达力。
有意思的地方是,在程序语言设计领域,按照传统思路,有些设计目标是互相冲突的。而Rust的优异之处在于,它能游刃有余地游走在各种设计目标之间,扬长避短,保持良好的妥协和平衡。
本书结构
本书将详细描述Rust语言的基本语法,穿插讲解一部分高级使用技巧,并尽量以更容易理解的方式向读者解释其背后的设计思想。语法只是基础,并非本书的重点,笔者更希望读者能理解到这些语法设计背后的理念,读完本书之后,可以从中受到一点启发,对程序语言有更多的认识,从而对编程本身有更深的理解。
Learning a language that is significantly different than you are used to is certainly tough at first, but it’s a great way to expand your horizons a bit.
在本书中,笔者尽量避免要求读者有很多的基础知识。当然,如果读者对其他的一种或多种编程语言有所了解更佳,其中包括C/C++的基础知识、内存错误、手动内存管理、自动垃圾回收、多线程并发和同步、操作系统相关的基础概念等。
本书共分为五个部分。
第一部分介绍Rust基本语法。因为对任何程序设计语言来说,语法都是基础,学习这部分是理解其他部分的前提。
第二部分介绍属于Rust独一无二的内存管理方式。它设计了一组全新的机制,既保证了安全性,又保持了强大的内存布局控制力,而且没有额外性能损失。这部分是本书的重点和核心所在,是Rust语言的思想内核精髓之处。
第三部分介绍Rust的抽象表达能力。它支持多种编程范式,以及较为强大的抽象表达
能力。
第四部分介绍并发模型。在目前这个阶段,对并行编程的支持是新一代编程语言无法绕过的重要话题。Rust也吸收了业界最新的发展成果,对并发有良好支持。
第五部分介绍一些实用设施。Rust语言有许多创新,但它绝不是高高在上、孤芳自赏的类型。设计者们在设计过程中充分考虑了语言的工程实用性。众多在其他语言中被证明过的优秀实践被吸收了进来,有利于提升实际工作效率。
为了内容的完整性,本书并没有严格按照知识点顺序组织内容,少数地方会直接使用后续章节中的知识点。笔者相信对读者来说,这不是一个很大的障碍,各位读者在碰到这种情况的时候,可以自行前后参照来理解。
总结和勘误
在计算机程序设计语言的领域中,一代又一代的语言潮起潮落,其兴起和衰落的节奏往往并非取决于技术本身的发展。对于Rust这门新出现的语言来说,以后究竟会有多大的影响,是否会成为取代某种语言的“新时代的宠儿”,实在难以预测,而且毫无必要预测。
笔者认为,Rust语言是最近若干年内系统级编程语言领域的集大成者之一。不论其最终发展如何,它的许多设计思想和令人惊叹的特性都值得大家学习。在本人的学习过程中,也时常为某些精彩的设计发出由衷的赞叹。
Rust语言是一门优秀的语言,同时也是门槛较高的一门语言,要完全掌握它不是一件很容易的事。因此,笔者并不希望将本书写成语言特性的逐一简单罗列,而更希望向读者解释清楚这些语言特性背后的设计思想。
所幸的是,Rust语言是完全开源的,不仅代码是开源的,而且整个设计过程、思辩讨论都是对社区完全开放的。它的许多非常有价值的学习资料,如同星星点点,散落在各个地方,包括官方文档、邮件列表、讨论组、GitHub、个人博客等。在学习和写作的过程中,能有幸一窥新语言创造者们的心路历程,也是难得的机缘。
要想把Rust语言的方方面面讲好、讲透,实在是一个无比繁重的任务。动笔之际,方知“看人挑担不吃力,自家挑担压断脊”,诚惶诚恐,战战兢兢,生怕有误人子弟之嫌。笔者水平有限,如有错漏,在所难免,欢迎读者批评指正。笔者将会在GitHub上发布最新的勘误列表,网址为https://github.com/F001/rust_book_feedback。读者可以在这个项目中新建bug提交问题,也可以通过邮件(rust-lang@qq.com)与笔者联系。同时也欢迎读者关注微信公众号:Rust编程,后面还会发布更多关于Rust的文章。
致谢
感谢Rust设计组,为软件开发行业创造了一份宝贵的财富。
感谢我所在的公司 synopsys给予的大力支持。
感谢梁自泽导师对我的培养。
感谢林春晓博士拨冗为本书做了最后一轮审校。
感谢妻子的包容和呵护,否则本书不可能面世。
感谢杨绣国编辑细致的工作。
感谢各位老师、同学和同事对我的支持,正是因为你们的帮助,才使我技术水平更上一层楼。

范长春(F001)
中国,武汉,2018年3月

上架指导

计算机\程序设计

封底文字

本书作者从Rust 0.7版起即开始关注学习这门编程语言,书中内容是其这些年来对所学知识的提炼和总结。本书并不满足于简要介绍Rust语言的语法规则,而是试图讲清楚它背后的设计原理和思想。希望读者看完这本书之后,能喜欢上Rust语言,并对Rust开源社区有所贡献。

本书的主要内容和特色:
全面完整地介绍了Rust语言的使用方法。
包含了Rust的最新功能。
用通俗易懂的文字总结归纳了Rust的设计思想。
始终使用源代码示例讲解每个知识点,力求精准无误。
通过实例演示了如何探寻Rust内部实现机制。
通过标准库源码分析,展现Rust的代码风格。
囊括了大量的官方入门书没有包含的高阶知识点。

作者简介

范长春 著:范长春(F001),中国科学院自动化研究所博士,Rust开源项目贡献者,前微软员工。目前就职于synopsys公司参与源代码静态检查工具coverity软件的开发工作。喜欢研究编译器以及源代码静态检查。在网上撰写了大量关于Rust语言的技术文章,得到了不错的反响。

图书目录

前言
第一部分 基础知识
第1章 与君初相见 2
1.1 版本和发布策略 2
1.2 安装开发环境 4
1.3 Hello World 7
1.4 Prelude 8
1.5 Format格式详细说明 8
第2章 变量和类型 10
2.1 变量声明 10
2.1.1 变量遮蔽 12
2.1.2 类型推导 13
2.1.3 类型别名 14
2.1.4 静态变量 15
2.1.5 常量 16
2.2 基本数据类型 16
2.2.1 bool 16
2.2.2 char 17
2.2.3 整数类型 17
2.2.4 整数溢出 19
2.2.5 浮点类型 21
2.2.6 指针类型 23
2.2.7 类型转换 23
2.3 复合数据类型 24
2.3.1 tuple 25
2.3.2 struct 25
2.3.3 tuple struct 27
2.3.4 enum 29
2.3.5 类型递归定义 32
第3章 语句和表达式 34
3.1 语句 34
3.2 表达式 34
3.2.1 运算表达式 35
3.2.2 赋值表达式 37
3.2.3 语句块表达式 38
3.3 if-else 39
3.3.1 loop 40
3.3.2 while 41
3.3.3 for循环 42
第4章 函数 44
4.1 简介 44
4.2 发散函数 46
4.3 main函数 47
4.4 const fn 48
4.5 函数递归调用 49
第5章 trait 50
5.1 成员方法 50
5.2 静态方法 53
5.3 扩展方法 55
5.4 完整函数调用语法 56
5.5 trait约束和继承 58
5.6 Derive 59
5.7 trait别名 60
5.8 标准库中常见的trait简介 61
5.8.1 Display和Debug 61
5.8.2 PartialOrd / Ord /
PartialEq / Eq 62
5.8.3 Sized 63
5.8.4 Default 64
5.9 总结 65
第6章 数组和字符串 66
6.1 数组 66
6.1.1 内置方法 67
6.1.2 多维数组 67
6.1.3 数组切片 67
6.1.4 DST和胖指针 68
6.1.5 Range 70
6.1.6 边界检查 72
6.2 字符串 74
6.2.1 &str 74
6.2.2 String 75
第7章 模式解构 77
7.1 简介 77
7.2 match 78
7.2.1 exhaustive 79
7.2.2 下划线 80
7.2.3 match也是表达式 82
7.2.4 Guards 83
7.2.5 变量绑定 84
7.2.6 ref和mut 85
7.3 if-let和while-let 88
7.4 函数和闭包参数做模式解构 89
7.5 总结 90
第8章 深入类型系统 91
8.1 代数类型系统 91
8.2 Never Type 94
8.3 再谈Option类型 97
第9章 宏 102
9.1 简介macro 102
9.1.1 实现编译阶段检查 102
9.1.2 实现编译期计算 103
9.1.3 实现自动代码生成 103
9.1.4 实现语法扩展 103
9.2 示范型宏 103
9.3 宏1.1 105
第二部分 内存安全
第10章 内存管理基础 110
10.1 堆和栈 110
10.2 段错误 111
10.3 内存安全 112
第11章 所有权和移动语义 114
11.1 什么是所有权 114
11.2 移动语义 116
11.3 复制语义 118
11.4 Box类型 120
11.5 Clone VS. Copy 121
11.5.1 Copy的含义 121
11.5.2 Copy 的实现条件 121
11.5.3 Clone的含义 122
11.5.4 自动derive 123
11.5.5 总结 123
11.6 析构函数 124
11.6.1 资源管理 125
11.6.2 主动析构 126
11.6.3 Drop VS. Copy 129
11.6.4 析构标记 129
第12章 借用和生命周期 132
12.1 生命周期 132
12.2 借用 132
12.3 借用规则 134
12.4 生命周期标记 136
12.4.1 函数的生命周期标记 136
12.4.2 类型的生命周期标记 138
12.5 省略生命周期标记 139
第13章 借用检查 141
13.1 编译错误示例 142
13.2 内存不安全示例:修改枚举 143
13.3 内存不安全示例:迭代器
失效 144
13.4 内存不安全示例:悬空指针 146
13.5 小结 148
第14章 NLL(Non-Lexical-
Lifetime) 150
14.1 NLL希望解决的问题 150
14.2 NLL的原理 154
14.3 小结 157
第15章 内部可变性 158
15.1 Cell 158
15.2 RefCell 161
15.3 UnsafeCell 164
第16章 解引用 169
16.1 自定义解引用 169
16.2 自动解引用 171
16.3 自动解引用的用处 171
16.4 有时候需要手动处理 173
16.5 智能指针 175
16.5.1 引用计数 175
16.5.2 Cow 178
16.6 小结 180
第17章 泄漏 181
17.1 内存泄漏 181
17.2 内存泄漏属于内存安全 184
17.3 析构函数泄漏 185
第18章 Panic 190
18.1 什么是panic 190
18.2 Panic实现机制 191
18.3 Panic Safety 192
18.4 小结 197
第19章 Unsafe 198
19.1 unsafe关键字 198
19.2 裸指针 199
19.3 内置函数 201
19.3.1 transmute 201
19.3.2 内存读写 202
19.3.3 综合示例 204
19.4 分割借用 206
19.5 协变 209
19.5.1 什么是协变 209
19.5.2 PhantomData 211
19.6 未定义行为 214
19.7 小结 215
第20章 Vec源码分析 216
20.1 内存申请 217
20.2 内存扩容 220
20.3 内存释放 222
20.3.1 Vec的析构函数 222
20.3.2 Drop Check 223
20.4 不安全的边界 226
20.5 自定义解引用 227
20.6 迭代器 228
20.7 panic safety 231
第三部分 高级抽象
第21章 泛型 234
21.1 数据结构中的泛型 234
21.2 函数中的泛型 235
21.3 impl块中的泛型 237
21.4 泛型参数约束 237
21.5 关联类型 241
21.6 何时使用关联类型 244
21.7 泛型特化 246
21.7.1 特化的意义 247
21.7.2 default上下文关键字 248
21.7.3 交叉 impl 250
第22章 闭包 252
22.1 变量捕获 254
22.2 move关键字 256
22.3 Fn/FnMut/FnOnce 257
22.4 闭包与泛型 259
22.5 闭包与生命周期 261
第23章 动态分派和静态分派 264
23.1 trait object 265
23.2 object safe 268
23.3 impl trait 271
第24章 容器与迭代器 275
24.1 容器 275
24.1.1 Vec 275
24.1.2 VecDeque 277
24.1.3 HashMap 277
24.1.4 BTreeMap 281
24.2 迭代器 283
24.2.1 实现迭代器 283
24.2.2 迭代器的组合 284
24.2.3 for循环 285
第25章 生成器 289
25.1 简介 289
25.2 对比迭代器 291
25.3 对比立即求值 292
25.4 生成器的原理 293
25.4.1 生成器原理简介 293
25.4.2 自引用类型 297
25.5 协程简介 298
第26章 标准库简介 302
26.1 类型转换 302
26.1.1 AsRef / AsMut 302
26.1.2 Borrow / BorrowMut 303
26.1.3 From / Into 304
26.1.4 ToOwned 305
26.1.5 ToString / FromStr 305
26.2 运算符重载 306
26.3 I/O 308
26.3.1 平台相关字符串 308
26.3.2 文件和路径 309
26.3.3 标准输入输出 310
26.3.4 进程启动参数 311
26.4 Any 311
第四部分 线程安全
第27章 线程安全 314
27.1 什么是线程 314
27.2 启动线程 316
27.3 免数据竞争 317
27.4 Send & Sync 320
第28章 详解Send和Sync 321
28.1 什么是Send 321
28.2 什么是Sync 322
28.3 自动推理 323
28.4 小结 324
第29章 状态共享 325
29.1 Arc 325
29.2 Mutex 326
29.3 RwLock 328
29.4 Atomic 329
29.5 死锁 331
29.6 Barrier 333
29.7 Condvar 334
29.8 全局变量 335
29.9 线程局部存储 336
29.10 总结 337
第30章 管道 339
30.1 异步管道 339
30.2 同步管道 341
第31章 第三方并行开发库 343
31.1 threadpool 343
31.2 scoped-threadpool 344
31.3 parking_lot 345
31.4 crossbeam 345
31.5 rayon 346
第五部分 实用设施
第32章 项目和模块 350
32.1 cargo 350
32.2 项目依赖 353
32.2.1 配置 355
32.2.2 workspace 355
32.2.3 build.rs 356
32.3 模块管理 358
32.3.1 文件组织 358
32.3.2 可见性 360
32.3.3 use关键字 362
第33章 错误处理 364
33.1 基本错误处理 364
33.2 组合错误类型 366
33.3 问号运算符 367
33.4 main函数中使用问号运算符 372
33.5 新的Failure库 373
第34章 FFI 375
34.1 什么是FFI 375
34.2 从C调用Rust库 376
34.3 从Rust调用C库 378
34.4 更复杂的数据类型 378
第35章 文档和测试 381
35.1 文档 381
35.2 测试 382
附录 词汇表 387

教学资源推荐
作者: Brian W.Kernighan,Rob Pike
作者: 顾元刚 等
作者: (美)Byron S.Gottfried
作者: 尹宝林 编著
参考读物推荐
作者: [美]罗布?法伯(Rob Farber) 编著
作者: Andre Lewis Michael Purvis;Jeffrey Sambells Cameron Turner
作者: 王洪影 著