本書通過探索多種系統(tǒng)編程概念和技術(shù)引入Rust編程語言,在深入探索計(jì)算機(jī)工作原理的同時(shí),幫助讀者了解Rust的所有權(quán)系統(tǒng)、Trait、包管理、錯(cuò)誤處理、條件編譯等概念,并通過源自現(xiàn)實(shí)的示例來幫助讀者了解Rust中的內(nèi)存模型、文件操作、多線程、網(wǎng)絡(luò)編程等內(nèi)容。
本書旨在幫助讀者理解如何用Rust進(jìn)行系統(tǒng)編程,并提供了一些使用Rust編寫代碼的技巧。本書給出了10余個(gè)源自現(xiàn)實(shí)的示例,讓讀者不僅能了解Rust語法,還能了解Rust的實(shí)際運(yùn)用。
本書適合所有對(duì)Rust感興趣的讀者閱讀。要更好地掌握本書涵蓋的內(nèi)容,讀者應(yīng)具備一定的編程經(jīng)驗(yàn),至少應(yīng)對(duì)計(jì)算機(jī)編程的基本概念有所了解。
*贈(zèng)送源代碼示例文件
*涵蓋數(shù)十個(gè)有趣的示例,簡(jiǎn)潔易懂,幫你了解Rust語法和Rust的實(shí)際運(yùn)用
*內(nèi)容由淺入深,通過探索多種系統(tǒng)編程概念和技術(shù)引入Rust編程語言,推薦給對(duì)rust編程感興趣的你!
蒂姆·麥克納馬拉(Tim McNamara),是文本挖掘、自然語言處理和數(shù)據(jù)工程等領(lǐng)域的專家。他是Rust Wellington(新西蘭Rust開發(fā)者活動(dòng))的組織者,并且定期通過社交網(wǎng)站主持Rust編程教學(xué)
第 一部分 Rust語言的特色
第 1章 Rust語言介紹 3
1.1 哪些地方使用了Rust? 4
1.2 在工作中提倡使用Rust 5
1.3 Rust初體驗(yàn) 6
1.3.1 直通“Hello, world!” 6
1.3.2 第 一個(gè)Rust程序 8
1.4 下載本書源代碼 10
1.5 使用Rust語言的感受如何 10
1.6 Rust語言是什么? 13
1.6.1 Rust的目標(biāo):安全性 14
1.6.2 Rust的目標(biāo):生產(chǎn)力 18
1.6.3 Rust的目標(biāo):控制 19
1.7 Rust的主要特點(diǎn) 20
1.7.1 性能 20
1.7.2 并發(fā) 21
1.7.3 內(nèi)存使用效率 21
1.8 Rust的缺點(diǎn) 21
1.8.1 循環(huán)數(shù)據(jù)結(jié)構(gòu) 21
1.8.2 編譯速度 22
1.8.3 嚴(yán)格 22
1.8.4 語言的大小 22
1.8.5 炒作 22
1.9 TLS安全性問題的研究 22
1.9.1 “心臟出血” 23
1.9.2 跳轉(zhuǎn)到失敗 23
1.10 Rust最適用于哪些領(lǐng)域? 25
1.10.1 命令行實(shí)用程序 25
1.10.2 數(shù)據(jù)處理 25
1.10.3 擴(kuò)展應(yīng)用程序 25
1.10.4 資源受限的環(huán)境 26
1.10.5 服務(wù)器端應(yīng)用 26
1.10.6 桌面應(yīng)用程序 26
1.10.7 桌面 26
1.10.8 移動(dòng)端 27
1.10.9 Web 27
1.10.10 系統(tǒng)編程 27
1.11 Rust的隱式特性:它的社區(qū) 27
1.12 Rust術(shù)語表 28
本章小結(jié) 28
第 2章 Rust語言基礎(chǔ) 29
2.1 創(chuàng)建一個(gè)可運(yùn)行的程序 30
2.1.1 編譯單文件的Rust程序 30
2.1.2 使用cargo編譯Rust項(xiàng)目 31
2.2 初探Rust語法 32
2.3 數(shù)字類型 34
2.3.1 整數(shù)和浮點(diǎn)數(shù) 34
2.3.2 整數(shù)的二進(jìn)制、八進(jìn)制及十六進(jìn)制表示法 35
2.3.3 數(shù)字的比較運(yùn)算 36
2.3.4 有理數(shù)、復(fù)數(shù)和其他數(shù)字類型 41
2.4 流程控制 43
2.4.1 for循環(huán):迭代的中心支柱 43
2.4.2 continue:跳過本次迭代余下的部分 45
2.4.3 while:循環(huán),直到循環(huán)條件改變了循環(huán)的狀態(tài) 45
2.4.4 loop:Rust循環(huán)結(jié)構(gòu)的基本組件 46
2.4.5 break:立即退出循環(huán) 46
2.4.6 if、if else和else:條件測(cè)試 47
2.4.7 match:類型感知的模式匹配 48
2.5 定義函數(shù) 50
2.6 使用引用 50
2.7 項(xiàng)目:繪制芒德布羅集 51
2.8 高級(jí)函數(shù)定義 54
2.8.1 顯式生命周期注解 54
2.8.2 泛型函數(shù) 55
2.9 創(chuàng)建grep-lite 58
2.10 使用數(shù)組、切片和動(dòng)態(tài)數(shù)組來創(chuàng)建數(shù)據(jù)列表 61
2.10.1 數(shù)組 61
2.10.2 切片 63
2.10.3 動(dòng)態(tài)數(shù)組 63
2.11 包含第三方代碼 65
2.11.1 增加對(duì)正則表達(dá)式的支持 66
2.11.2 生成包的本地化文檔 67
2.11.3 使用rustup管理Rust工具鏈 68
2.12 命令行參數(shù)的支持 68
2.13 從文件中讀取 70
2.14 從標(biāo)準(zhǔn)輸入中讀取 72
本章小結(jié) 73
第3章 復(fù)合數(shù)據(jù)類型 75
3.1 使用普通函數(shù)對(duì)API進(jìn)行實(shí)驗(yàn) 76
3.2 使用結(jié)構(gòu)體為文件建!77
3.3 使用impl為結(jié)構(gòu)體添加方法 81
3.4 返回錯(cuò)誤信息 84
3.4.1 修改一個(gè)著名的全局變量 85
3.4.2 使用Result作為返回類型 88
3.5 定義并使用枚舉體 91
3.6 使用trait來定義共有的行為 95
3.6.1 創(chuàng)建名為Read的trait 95
3.6.2 為類型實(shí)現(xiàn)std::fmt::Display 96
3.7 將類型暴露給外部使用 99
3.8 創(chuàng)建內(nèi)聯(lián)文檔 100
3.8.1 使用rustdoc給單個(gè)源文件生成文檔 101
3.8.2 使用cargo為一個(gè)包及其依賴的包生成文檔 101
本章小結(jié) 103
第4章 生命周期、所有權(quán)和借用 104
4.1 實(shí)現(xiàn)一個(gè)模擬的立方體衛(wèi)星地面站 105
4.1.1 遇到第 一個(gè)生命周期問題 106
4.1.2 基本類型的特殊行為 109
4.2 本章圖例的說明 110
4.3 所有者是什么?它有什么職責(zé)? 111
4.4 所有權(quán)是如何移動(dòng)的? 112
4.5 解決所有權(quán)的問題 114
4.5.1 在不需要完整所有權(quán)的地方,使用引用 116
4.5.2 使用更少的長存活期的值 119
4.5.3 在需要完整所有權(quán)的地方,復(fù)制長存活期的值 124
4.5.4 把數(shù)據(jù)包裝到特殊的類型中 127
本章小結(jié) 129
第二部分 揭開系統(tǒng)編程的神秘面紗
第5章 深入理解數(shù)據(jù) 133
5.1 位模式和類型 133
5.2 整數(shù)的生存范圍 135
5.3 小數(shù)的表示形式 139
5.4 浮點(diǎn)數(shù) 139
5.4.1 觀察f32的內(nèi)部 140
5.4.2 分離出符號(hào)位 141
5.4.3 分離出指數(shù) 142
5.4.4 分離出尾數(shù) 143
5.4.5 剖析一個(gè)浮點(diǎn)數(shù) 145
5.5 定點(diǎn)數(shù)格式 147
5.6 從隨機(jī)字節(jié)中生成隨機(jī)概率 151
5.7 實(shí)現(xiàn)一個(gè)CPU模擬器以建立函數(shù)也是數(shù)據(jù)的觀念 153
5.7.1 CPU原型1:加法器 153
5.7.2 CPU原型1完整的清單 157
5.7.3 CPU原型2:累加器 159
5.7.4 CPU原型3:調(diào)用函數(shù) 162
5.7.5 CPU 4:添加額外功能 168
本章小結(jié) 168
第6章 內(nèi)存 169
6.1 指針 169
6.2 探索Rust的引用和指針類型 171
6.2.1 Rust中的原始指針 176
6.2.2 Rust指針的生態(tài)系統(tǒng) 178
6.2.3 智能指針構(gòu)建塊 180
6.3 為程序提供存儲(chǔ)數(shù)據(jù)的內(nèi)存 181
6.3.1 !181
6.3.2 堆 183
6.3.3 什么是動(dòng)態(tài)內(nèi)存分配? 187
6.3.4 分析動(dòng)態(tài)內(nèi)存分配的影響 192
6.4 虛擬內(nèi)存 194
6.4.1 背景 195
6.4.2 第 一步:讓一個(gè)進(jìn)程來掃描它自己的內(nèi)存 196
6.4.3 把虛擬地址翻譯為物理地址 198
6.4.4 第二步:通過操作系統(tǒng)來掃描地址空間 201
6.4.5 第三步:讀取和寫入進(jìn)程內(nèi)存中的字節(jié)數(shù)據(jù) 203
本章小結(jié) 203
第7章 文件與存儲(chǔ) 204
7.1 文件格式是什么? 204
7.2 創(chuàng)建你自己的用于存儲(chǔ)數(shù)據(jù)的文件格式 206
7.3 實(shí)現(xiàn)一個(gè)hexdump的克隆 208
7.4 Rust中的文件操作 211
7.4.1 使用Rust打開一個(gè)文件并控制文件的模式 211
7.4.2 使用std::fs::Path以一種類型安全的方式與文件系統(tǒng)進(jìn)行交互 212
7.5 使用基于日志結(jié)構(gòu)、僅追加的存儲(chǔ)架構(gòu),來實(shí)現(xiàn)一個(gè)鍵值存儲(chǔ) 213
7.5.1 鍵值模型 213
7.5.2 講解actionkv v1:一個(gè)帶有命令行接口的內(nèi)存中的鍵值存儲(chǔ) 214
7.6 Actionkv v1:前端代碼 215
7.7 理解ACTIONKV的核心:LIBACTIONKV包 219
7.7.1 初始化ActionKV結(jié)構(gòu)體 219
7.7.2 處理單條記錄 221
7.7.3 以確定的字節(jié)順序?qū)⒍嘧止?jié)二進(jìn)制數(shù)據(jù)寫入磁盤 223
7.7.4 使用校驗(yàn)和來驗(yàn)證I/O錯(cuò)誤 225
7.7.5 向已存在的數(shù)據(jù)庫中插入一個(gè)新的鍵值對(duì) 227
7.7.6 actionkv的完整清單 228
7.7.7 使用HashMap和BTreeMap來處理鍵和值 232
7.7.8 創(chuàng)建一個(gè)HashMap并用值來填充它 234
7.7.9 從HashMap和BTreeMap中來檢索值 235
7.7.10 在HashMap和BTreeMap之間如何選擇 236
7.7.11 給actionkv v2.0添加數(shù)據(jù)庫索引 237
本章小結(jié) 240
第8章 網(wǎng)絡(luò) 242
8.1 全部的網(wǎng)絡(luò)體系都在7個(gè)分層中 243
8.2 使用reqwest來生成一個(gè)HTTP GET請(qǐng)求 245
8.3 trait對(duì)象 247
8.3.1 trait對(duì)象能做什么? 247
8.3.2 trait對(duì)象是什么? 247
8.3.3 創(chuàng)建一個(gè)微型的角色扮演游戲:rpg項(xiàng)目 248
8.4 TCP 251
8.4.1 端口號(hào)是什么? 252
8.4.2 把主機(jī)名轉(zhuǎn)換為IP地址 252
8.5 以符合工效學(xué)的方式處理來自多個(gè)包的錯(cuò)誤 258
8.5.1 問題:無法返回多種錯(cuò)誤類型 259
8.5.2 通過定義錯(cuò)誤類型來包裝下游的錯(cuò)誤 262
8.5.3 使用unwrap()和expect()來“作弊” 267
8.6 MAC地址 268
8.7 使用Rust的枚舉體來實(shí)現(xiàn)狀態(tài)機(jī) 271
8.8 原始TCP 272
8.9 創(chuàng)建一個(gè)虛擬網(wǎng)絡(luò)設(shè)備 272
8.10 原始HTTP 273
本章小結(jié) 282
第9章 時(shí)間與時(shí)間保持 283
9.1 背景 284
9.2 時(shí)間源 285
9.3 一些相關(guān)的術(shù)語定義 286
9.4 時(shí)間的編碼 287
9.5 clock v0.1.0:教會(huì)一個(gè)應(yīng)用程序如何報(bào)時(shí) 288
9.6 clock v0.1.1:格式化時(shí)間戳以符合ISO 8601和電子郵件的標(biāo)準(zhǔn) 289
9.6.1 重構(gòu)clock v0.1.0的代碼以支持更廣泛的體系結(jié)構(gòu) 290
9.6.2 時(shí)間的格式化 291
9.6.3 提供一個(gè)完整的命令行接口 291
9.6.4 clock v0.1.1:完整的項(xiàng)目代碼 293
9.7 clock v0.1.2:設(shè)置時(shí)間 295
9.7.1 相同的行為模式 295
9.7.2 給使用libc的操作系統(tǒng)來設(shè)置時(shí)間 296
9.7.3 在Windows上設(shè)置時(shí)間 298
9.7.4 clock v0.1.2:完整的清單 300
9.8 改善錯(cuò)誤處理 303
9.9 clock v0.1.3:使用NTP來解決時(shí)鐘之間的差異 304
9.9.1 發(fā)送NTP請(qǐng)求并解析響應(yīng) 304
9.9.2 依據(jù)服務(wù)器的響應(yīng)來調(diào)整本地時(shí)間 306
9.9.3 在使用了不同的精度和紀(jì)元的時(shí)間表示法之間進(jìn)行轉(zhuǎn)換 308
9.9.4 clock v0.1.3:完整的清單 309
本章小結(jié) 316
第 10章 進(jìn)程、線程和容器 318
10.1 匿名函數(shù) 319
10.2 產(chǎn)生線程 320
10.2.1 引入閉包 320
10.2.2 產(chǎn)生一個(gè)新線程 321
10.2.3 產(chǎn)生幾個(gè)線程的效果 321
10.2.4 產(chǎn)生很多個(gè)線程的效果 322
10.2.5 重新生成這些結(jié)果 324
10.2.6 共享的變量 328
10.3 閉包與函數(shù)的差異 330
10.4 從多線程解析器和代碼生成器中程序化地生成頭像 331
10.4.1 如何運(yùn)行render-hex以及預(yù)期的輸出 331
10.4.2 單線程版本render-hex的概要介紹 333
10.4.3 為每個(gè)邏輯上的任務(wù)產(chǎn)生一個(gè)線程 341
10.4.4 使用線程池和任務(wù)隊(duì)列 343
10.5 并發(fā)與任務(wù)虛擬化 350
10.5.1 線程 352
10.5.2 上下文切換是什么? 352
10.5.3 進(jìn)程 353
10.5.4 WebAssembly 353
10.5.5 容器 353
10.5.6 為什么要使用操作系統(tǒng)呢? 354
本章小結(jié) 354
第 11章 內(nèi)核 355
11.1 初級(jí)操作系統(tǒng)(FledgeOS) 355
11.1.1 搭建開發(fā)環(huán)境,用于開發(fā)操作系統(tǒng)內(nèi)核 355
11.1.2 驗(yàn)證開發(fā)環(huán)境 357
11.2 Fledgeos-0:先讓一些東西能運(yùn)行起來 358
11.2.1 第 一次引導(dǎo)啟動(dòng) 358
11.2.2 編譯的步驟 359
11.2.3 源清單 360
11.2.4 處理panic 364
11.2.5 使用VGA兼容的文本模式寫入屏幕 365
11.2.6 _start():FledgeOS的main()函數(shù) 366
11.3 fledgeos-1:避免使用忙循環(huán) 367
11.3.1 通過直接與CPU交互來降低功耗 367
11.3.2 fledgeos-1的源代碼 368
11.4 fledgeos-2:自定義異常處理 369
11.4.1 幾乎可以正確地處理異!369
11.4.2 fledgeos-2的源代碼 369
11.5 fledgeos-3:文本的輸出 370
11.5.1 把彩色的文本輸出到屏幕 371
11.5.2 控制枚舉體的內(nèi)存表示形式 371
11.5.3 為何要使用枚舉體? 372
11.5.4 創(chuàng)建出一個(gè)類型,能夠用來輸出到VGA的幀緩沖區(qū) 372
11.5.5 輸出到屏幕 373
11.5.6 fledgeos-3的源代碼 373
11.6 fledgeos-4:自定義恐慌處理 375
11.6.1 實(shí)現(xiàn)一個(gè)恐慌處理程序,能夠向用戶報(bào)告錯(cuò)誤 375
11.6.2 使用core::fmt::Write來重新實(shí)現(xiàn)panic() 376
11.6.3 實(shí)現(xiàn)core::fmt::Write 376
11.6.4 fledgeos-4的源代碼 377
本章小結(jié) 379
第 12章 信號(hào)、中斷和異!380
12.1 術(shù)語表 380
12.2 中斷是如何影響應(yīng)用程序的? 383
12.3 軟件中斷 384
12.4 硬件中斷 385
12.5 信號(hào)處理 386
12.5.1 默認(rèn)的行為 386
12.5.2 用來暫停和恢復(fù)一個(gè)程序的操作 386
12.5.3 列出操作系統(tǒng)支持的所有信號(hào) 389
12.6 使用自定義的行為來處理信號(hào) 389
12.6.1 在Rust中使用全局變量 390
12.6.2 使用全局變量來指示已經(jīng)啟動(dòng)了關(guān)機(jī) 392
12.7 發(fā)送由應(yīng)用程序定義的信號(hào) 394
12.8 如何忽略信號(hào)? 396
12.9 從深層嵌套的調(diào)用棧中關(guān)閉程序 397
12.9.1 sjlj項(xiàng)目的介紹 399
12.9.2 在程序中設(shè)置固有函數(shù) 399
12.9.3 把指針轉(zhuǎn)換成其他類型 401
12.9.4 編譯sjlj項(xiàng)目 402
12.9.5 sjlj項(xiàng)目的源代碼 403
12.10 將這些技術(shù)應(yīng)用于不支持信號(hào)的平臺(tái)的說明 406
12.11 修訂異!406
本章小結(jié) 406