本书目的
系统讲解Rust编程语言,帮助读者掌握Rust网络服务器、游戏开发、数据分析等方面的基础编程技能。学习Rust编程,做一下技术储备。
内容简介
Rust是一门系统编程语言,专注于安全,尤其是并发安全,它也是支持函数式、命令式以及泛型等编程范式的多范式语言。标准Rust在语法和性能上和标准C++类似,设计者可以在保证性能的同时提供更好的内存安全。本书详解Rust编程技巧,配套示例源码、PPT课件、作者QQ答疑服务。
本书共分17章,内容包括Rust基础,搭建Rust开发环境,常量、变量和标量数据类型,运算符和格式化输出,选择结构,控制结构,函数,复合数据类型,指针,模块化编程和标准库,标准库中的字符串对象,多线程编程,标准输入输出和命令行参数,文件读写,网络编程实战,图像和游戏开发实战,数据分析实战。
适合的读者
本书适用于Rust编程初学者、Rust应用开发人员、高并发和分布式开发人员、Web Assembly开发人员、游戏开发人员以及嵌入式应用开发人员。本书也适合作为高等院校或高职高专Rust编程课程的教材。
作者简介
朱文伟,名校计算机专业统招硕士,20多年C\C++、Java开发经验。主导开发过密码、图形、人工智能等产品。精通Linux、Windows系统开发及数据库开发技术。著有图书:
《嵌入式Linux驱动开发实践》《高性能Linux网络编程核心技术揭秘》《Linux C/C++服务器开发实践》《Qt 6.x从入门到精通》《PyQt 5从入门到精通》《Linux C与C++ 一线开发实践》《Visual C++2017从入门到精通》《Windows C/C++加密解密实战》《密码学原理与Java实现》《OpenCV 4.5计算机视觉开发实战(基于VC++)》《OpenCV 4.5计算机视觉开发实战:基于Python》。
前言
笔者一直在讲究性能的领域做开发,比如网络服务器、算法、图像、游戏以及嵌入式等。这些领域通常只能用C/C++,因为C/C++是相对高效的编程语言。但这哥俩比较调皮,稍微没看好它们,它们就会闯个祸,弄个纰漏,导致系统的稳定性一直让人提心吊胆。有时真羡慕隔壁项目组使用Java的老兄,毕竟Java以安全稳定和跨平台著称,但Java天生性能一般,所以应用得也不是很广。为此,笔者经常仰天长叹,C和Java为何不能合二为一!
Rust应运而生。Rust站在了前人的肩膀上,借助最近几十年的语言研究成果,创造出了所有权与生命周期等崭新的概念。相对于C/C++等传统语言,它具有天生的安全性。换句话说,你无法在安全的Rust代码中执行任何非法的内存操作。相对于C#等带有垃圾回收机制的语言来讲,它遵循了零开销抽象(Zero-Cost Abstraction)规则,并为开发者保留了最大的底层控制能力。
可见,Rust不但具有C/C++的性能,而且具有C/C++不具备的安全性。所以它能替代传统的C/C++应用场合,比如嵌入式开发和服务器开发等,而且更适合这些场合,因为这些场合除性能要求高外,对健壮性要求也非常高,而Rust能主动帮助程序员规避传统C/C++程序员经常犯的错误。可见,Rust前途非常光明,大有取代C/C++的趋势,这也是大公司新项目采用它的原因。
Rust由开源基金会Mozilla推动开发,它的背后有一个完善且热情的社区。年轻的Rust正在众人合力推动之下不断进步,许多像你我一样的开发者共同决定着Rust的前进方向。你能够在Rust的托管网站GitHub上追踪到最新的源代码及开发进展,甚至是参与到Rust本身的开发中。但不得不承认的是,Rust独特的创新性也给我们带来了突兀的学习曲线。这些概念与传统语言雕刻在我们脑海中的回路是如此的不同,以至于使众多初学者望而却步。这让人无比遗憾。于是,一直提倡学习曲线要平缓的笔者撰写了本书,希望能对Rust的推广起到一个添砖加瓦和抛砖引玉的作用。
Rust作为开源的、跨平台的系统级编程语言,可以帮助你编写出更为快速且更为可靠的软件,在给予开发者底层控制能力的同时,通过深思熟虑的工程设计,避免了传统语言带来的诸多麻烦。
关于本书
本书由浅入深地探讨了Rust语言的方方面面。全书共分17章,从Windows和Linux的Rust开发环境搭建,到基本的语言语法、函数、选择、循环结构,再到复杂的数据类型、字符串、指针、多线程、标准库、文件读写,最后到网络编程实战、图像与游戏编程实战、数据分析实战,基本覆盖了Rust开发所需要的常见知识。
另外,笔者并没有把一些冷门、生僻和不常用的知识介绍给大家,因为学这些内容“性价比”太低,还会打击初学者的信心。总之,笔者认为对于初学者而言,学习曲线一定要平缓,因此设计的网络案例、游戏案例、数据分析案例也是短小精悍,尽量给读者带来启发。
配套资源下载
本书配套示例源代码、PPT课件、作者QQ答疑服务,需要用微信扫描下面的二维码获取。如果阅读中发现问题或有疑问,请联系booksaga@163.com,邮件主题写“Rust编程与项目实战”。
碍于作者能力有限,本书难免存在疏漏之处,还望读者不吝赐教,我们会随着Rust的迭代升级,不断对本书进行更新与勘误。作者答疑QQ参见配套下载资源。
作者
2024年1月
目录
目 录
第 1 章 Rust基础 1
1.1 Rust概述 1
1.1.1 Rust的来源与定义 1
1.1.2 Rust适合做什么 2
1.1.3 Rust的特点 3
1.1.4 Rust和其他语言的总体比较 4
1.2 Rust到底值不值得学 5
1.2.1 Rust是一种全面创新的语言 6
1.2.2 引用和借用 8
1.2.3 生命期 9
1.2.4 编译时检查和运行时开销 10
1.2.5 有限的面向对象特征 11
1.2.6 扩展库支持 13
1.2.7 Rust是一种可以进行底层开发的高级语言 14
第 2 章 搭建Rust开发环境 15
2.1 搭建Windows下的Rust开发环境 15
2.1.1 安装vs_buildtools 15
2.1.2 安装Rust相关工具 16
2.1.3 第一个Rust项目 17
2.1.4 VS Code搭建Rust开发环境 18
2.1.5 VS Code单步调试Rust程序 20
2.1.6 VS Code自动清除输出窗口 22
2.1.7 VS Code修改程序自动保存 23
2.1.8 关闭rust-analyzer插件的自动类型提示 23
2.2 在Linux下搭建Rust开发环境 24
2.2.1 安装基本开发工具 24
2.2.2 启用SSH 24
2.2.3 安装C编译工具 26
2.2.4 安装和配置Rust编译环境 27
2.2.5 命令行开发Rust程序 28
2.2.6 在VS Code中开发远程Rust程序 30
第 3 章 常量、变量和标量数据类型 39
3.1 Rust程序结构 39
3.2 注释 41
3.3 常量 42
3.3.1 常量的定义 42
3.3.2 直接常量 42
3.3.3 const常量 43
3.4 变量 44
3.4.1 Rust中的关键字 45
3.4.2 变量的命名规则 46
3.4.3 变量的定义 47
3.4.4 变量的赋值 48
3.4.5 变量的初始化 49
3.4.6 变量的可变性 49
3.4.7 变量遮蔽 50
3.4.8 字符串变量 51
3.5 数据类型的定义和分类 52
3.6 标量数据类型 53
3.6.1 整型 53
3.6.2 布尔型 57
3.6.3 字符类型 57
3.6.4 浮点型 58
3.6.5 得到变量的字节数 59
3.7 常数的数据类型 60
3.8 作用域 61
3.9 所有权 63
3.9.1 让我们回忆栈和堆 63
3.9.2 什么是所有权 63
第 4 章 运算符和格式化输出 65
4.1 运算符 65
4.1.1 赋值运算符 65
4.1.2 数学运算符 66
4.1.3 组合运算符 66
4.1.4 关系运算符 67
4.1.5 逻辑运算符 68
4.1.6 位运算符 69
4.1.7 变量类型转换运算符 70
4.1.8 运算符的优先级 71
4.2 格式化输出宏 72
4.2.1 默认输出 73
4.2.2 通配符{} 73
4.2.3 通配符和位置 73
4.2.4 通配符和命名参数 74
4.2.5 输出不同的进制数 74
4.2.6 指定宽度 76
4.2.7 填充与对齐 77
4.2.8 指定小数的精确值 78
4.2.9 输出{和} 79
4.2.10 格式化宏format! 80
第 5 章 选择结构 81
5.1 if选择语句 81
5.1.1 单分支if语句 82
5.1.2 双分支if…else语句 83
5.1.3 多分支if语句 83
5.1.4 在let语句中使用if 86
5.2 匹配控制语句match 86
5.2.1 匹配整数 87
5.2.2 匹配枚举类型 87
5.2.3 匹配元组 88
5.2.4 匹配范围 88
5.2.5 匹配守卫 89
5.2.6 一些经验 89
第 6 章 控制结构 91
6.1 生活及数学中的循环控制 91
6.2 for循环 91
6.3 while循环 92
6.4 loop循环 93
6.5 break语句 93
6.5.1 break单独使用 94
6.5.2 break带出返回值 94
6.5.3 跳转到指定标签的循环 95
6.6 continue语句 96
6.6.1 continue单独使用 96
6.6.2 跳转到指定标签的循环 97
第 7 章 函数 99
7.1 函数定义 99
7.2 函数参数 100
7.3 函数返回值 100
7.4 函数重载 101
7.5 函数作为参数和返回值 102
7.6 Rust泛型 102
7.6.1 什么是泛型编程 102
7.6.2 在函数中使用泛型 103
7.6.3 在结构体中使用泛型 106
第 8 章 复合数据类型 108
8.1 数组 108
8.1.1 什么是数组 108
8.1.2 数组的定义和初始化 109
8.1.3 输出数组元素 110
8.1.4 得到数组长度 110
8.1.5 默认值初始化 110
8.1.6 访问数组元素 111
8.1.7 数组切片 111
8.1.8 多维数组 113
8.2 元组 113
8.2.1 元组的定义 113
8.2.2 元组的输出 114
8.2.3 访问元组中的单个元素 114
8.3 结构体类型 115
8.3.1 结构体的定义 116
8.3.2 结构体实例化 116
8.3.3 结构体的方法 117
8.3.4 结构体的关联函数 118
8.3.5 结构体的特性 119
8.3.6 结构体的注意事项 119
8.4 枚举类型 120
8.4.1 定义枚举类型 120
8.4.2 枚举类型的使用 122
8.4.3 包含数据的枚举 123
8.4.4 some类型 124
8.5 trait 125
8.5.1 成员方法 125
8.5.2 静态方法 128
8.5.3 扩展方法 129
8.5.4 完整函数调用方法 130
8.5.5 trait约束和继承 131
8.5.6 derive属性 132
8.5.7 trait别名 133
8.5.8 Sized trait 133
8.5.9 默认trait 134
第 9 章 指针 135
9.1 指针的概念 135
9.1.1 地址和指针 135
9.1.2 指针变量的定义 136
9.2 指针变量的基本使用方法 137
9.2.1 指针变量的赋值 137
9.2.2 得到指针变量的大小 138
9.2.3 得到指针变量所指变量的值 139
9.2.4 指针变量做函数参数 140
9.2.5 指针变量做函数返回值 141
9.2.6 数组通过指针来引用 142
9.3 函数指针 143
9.3.1 什么是函数指针 143
9.3.2 用函数指针变量调用函数 143
9.3.3 函数指针做函数参数 146
9.4 指针数组 148
第 10 章 模块化编程和标准库 150
10.1 箱 151
10.1.1 创建crate库 151
10.1.2 创建可执行的crate 152
10.1.3 可执行crate调用crate库 152
10.2 包 153
10.2.1 创建可执行类型的包 154
10.2.2 仅编译包 155
10.2.3 创建库类型的包 155
10.2.4 包管理工具Cargo 157
10.2.5 典型的包结构 158
10.2.6 引用外部库 160
10.3 模块 164
10.3.1 模块的定义 164
10.3.2 模块的结构 165
10.3.3 模块的访问控制 166
10.3.4 模块的基本使用 169
10.3.5 创建嵌套模块 169
10.3.6 多模块多文件 174
10.4 工作区的概念 177
10.5 标准库概述 177
第 11 章 标准库中的字符串对象 180
11.1 概述 180
11.2 创建字符串对象 180
11.3 字符串对象常用的方法 182
11.3.1 as_bytes得到字符串内容的字节切片 182
11.3.2 as_mut_str转换字符串的可变性 182
11.3.3 as_str提取整个字符串切片 182
11.3.4 capacity获得此字符串的缓冲区容量 183
11.3.5 clear删除字符串内容 183
11.3.6 drain删除部分字符串 183
11.3.7 from_raw_parts创建新的字符串 184
11.3.8 from_utf16将UTF-16编码的矢量解码为字符串 184
11.3.9 from_utf8将字节向量转换为字符串 185
11.3.10 insert插入一个字符 185
11.3.11 insert_str插入一个字符串切片 186
11.3.12 into_bytes将字符串转换为字节向量 186
11.3.13 is_empty判断字符串长度是否为零 186
11.3.14 len得到字符串长度 186
11.3.15 new创建一个新的空字符串 187
11.3.16 with_capacity创建指定容量的新空字符串 187
11.3.17 push追加字符 187
11.3.18 push_str追加字符串 188
11.3.19 truncate缩短字符串 188
11.3.20 pop删除最后一个字符 188
11.3.21 remove删除指定字符 190
11.3.22 reserve保留容量 191
11.3.23 shrink_to使用下限缩小此字符串的容量 191
11.3.24 shrink_to_fit缩小此字符串
的容量 192
11.3.25 split_off分割字符串 192
11.3.26 truncate缩短字符串 192
第 12 章 多线程编程 193
12.1 闭包 193
12.1.1 闭包的定义和语法 193
12.1.2 捕获变量 194
12.1.3 闭包作为参数和返回值 195
12.1.4 闭包的使用场景 195
12.2 多线程编程概述 196
12.2.1 线程的基本概念 196
12.2.2 并发 196
12.2.3 Rust线程模型 197
12.3 模块std::thread 197
12.3.1 spawn创建线程 197
12.3.2 等待所有线程完成 199
12.3.3 在线程中使用其他线程数据 202
12.3.4 线程函数 204
12.3.5 available_parallelism返回默认并行度 205
12.3.6 获得当前线程的名称和id 206
12.4 线程间通信 208
第 13 章 标准输入输出和命令行参数 209
13.1 概述 209
13.2 从标准输入流中读取数据 210
13.2.1 trait Read 210
13.2.2 trait BufRead 212
13.2.3 标准输入函数stdin 213
13.3 标准输出流 215
13.4 命令行参数 217
第 14 章 文件读写 219
14.1 打开文件 219
14.2 创建文件 220
14.3 写文件 221
14.4 读文件 221
14.5 追加内容到文件末尾 222
14.6 删除文件 223
14.7 复制文件 224
第 15 章 网络编程实战 225
15.1 套接字的基本概念 225
15.1.1 网络程序的架构 226
15.1.2 套接字的类型 227
15.2 IP地址枚举IpAddr 228
15.2.1 is_unspecified函数 229
15.2.2 is_loopback函数 229
15.2.3 is_multicast函数 230
15.2.4 is_ipv4函数 230
15.2.5 is_ipv6函数 230
15.3 IPv4结构Ipv4Addr 231
15.3.1 new函数 231
15.3.2 常量LOCALHOST 232
15.3.3 常量UNSPECIFIED 232
15.3.4 常量BROADCAST 232
15.3.5 octets函数 232
15.3.6 is_unspecified函数 233
15.3.7 is_loopback函数 233
15.3.8 is_link_local函数 233
15.3.9 is_multicast函数 234
15.3.10 is_broadcast函数 234
15.3.11 to_ipv6_compatible函数 235
15.3.12 to_ipv6_mapped函数 235
15.4 IPv4套接字地址SocketAddrV4 235
15.4.1 new函数 236
15.4.2 ip函数 236
15.4.3 set_ip函数 236
15.4.4 port函数 237
15.4.5 set_port函数 237
15.5 TCP套接字编程的基本步骤 237
15.6 TCP侦听器TcpListener 238
15.6.1 bind函数 239
15.6.2 local_addr函数 239
15.6.3 try_clone函数 240
15.6.4 accept函数 240
15.6.5 incoming函数 241
15.6.6 set_ttl函数 241
15.6.7 ttl函数 242
15.6.8 take_error函数 242
15.6.9 set_nonblocking函数 242
15.7 TCP流结构TcpStream 243
15.7.1 connect函数 243
15.7.2 connect_timeout函数 244
15.7.3 peer_addr函数 244
15.7.4 local_addr函数 245
15.7.5 shutdown函数 245
15.7.6 try_clone函数 245
15.7.7 set_read_timeout函数 246
15.7.8 set_write_timeout函数 246
15.7.9 read_timeout函数 247
15.7.10 write_timeout函数 247
15.7.11 peek函数 247
15.7.12 set_nodelay函数 248
15.7.13 nodelay函数 248
15.7.14 set_ttl函数 248
15.7.15 ttl函数 249
15.7.16 take_error函数 249
15.7.17 set_nonblocking函数 249
15.8 实战TCP服务器客户端编程 250
15.9 UDP套接字结构UdpSocket 251
15.9.1 bing函数 252
15.9.2 recv_from函数 253
15.9.3 peek_from函数 253
15.9.4 send_to函数 253
15.9.5 peer_addr函数 254
15.9.6 local_addr函数 254
15.9.7 local_addr函数 254
15.9.8 set_read_timeout函数 255
15.9.9 set_write_timeout函数 255
15.9.10 read_timeout函数 256
15.9.11 write_timeout函数 256
15.9.12 set_broadcast函数 256
15.9.13 broadcast函数 257
15.9.14 set_multicast_loop_v4函数 257
15.9.15 multicast_loop_v4函数 257
15.9.16 set_multicast_ttl_v4函数 257
15.9.17 multicast_ttl_v4函数 258
15.9.18 set_multicast_loop_v6函数 258
15.9.19 multicast_loop_v6函数 258
15.9.20 set_ttl函数 259
15.9.21 ttl函数 259
15.9.22 take_error函数 259
15.9.23 connect函数 260
15.9.24 send函数 260
15.9.25 recv函数 260
15.9.26 peek函数 261
15.9.27 set_nonblocking函数 261
15.9.28 实战UDP编程 262
15.10 网络实战案例 263
15.10.1 HTTP的工作原理 263
15.10.2 HTTP的特点 264
15.10.3 HTTP消息结构 264
15.10.4 客户端请求消息 265
15.10.5 服务器响应消息 266
15.10.6 HTTP状态码 267
15.10.7 HTTP状态码分类 267
15.10.8 实现HTTP服务器 268
第 16 章 图像和游戏开发实战 271
16.1 图像编程基础 271
16.2 Piston概述 273
16.3 WindowSettings结构体 274
16.3.1 new函数 274
16.3.2 build函数 274
16.3.3 get_title函数 274
16.3.4 set_title函数 274
16.3.5 title函数 275
16.3.6 get_size函数 275
16.3.7 set_size函数 275
16.3.8 size函数 275
16.3.9 get_fullscreen函数 275
16.3.10 set_fullscreen函数 275
16.3.11 fullscreen函数 275
16.3.12 get_exit_on_esc函数 276
16.3.13 set_exit_on_esc函数 276
16.3.14 exit_on_esc函数 276
16.3.15 get_automatic_close函数 276
16.3.16 set_automatic_close函数 276
16.3.17 automatic_close函数 276
16.4 piston_window库 280
16.5 游戏实战案例 286
第 17 章 数据分析实战 295
17.1 Polars概述 295
17.1.1 什么是Polars 295
17.1.2 Polars和Pandas对比 296
17.1.3 为什么需要Polars 296
17.1.4 安装Polars 297
17.1.5 创建DataFrame 297
17.1.6 加载外部数据 301
17.2 浏览数据 303
17.3 数据描述 304
17.4 聚合统计 305
17.5 数据清洗 306
17.5.1 处理缺失值 306
17.5.2 剔除重复值 307
17.6 数据操作 308
17.6.1 选择列 308
17.6.2 数据筛选(过滤) 308
17.6.3 排序 309
17.6.4 合并 310
17.6.5 分组 311