Rust程序設計(第2版) Programming Rust: Fast, Safe Systems Development, 2/e
[美]吉姆·布蘭迪(Jim Blandy)[美]賈森·奧倫多夫(Jason Orendorff)[美]莉奧諾拉·F. S. 廷德爾(Leonora F. S. Tindall)
相關主題
商品描述
本書是Rust領域經典參考書,由業內資深系統程序員編寫,廣受讀者好評。
書中系統介紹了Rust這種新型系統編程語言——具有非常好的安全性,兼具C和C++的高性能,並大大簡化了並發程序的編寫。第2版對上一版內容進行了重組和完善,新增了對“異步編程”的介紹。借助書中的大量案例,你也能用Rust編寫出兼顧安全性與高性能的程序。本書內容包括基本數據類型、所有權、引用、表達式、錯誤處理、crate與模塊、結構、枚舉與模式等基礎知識,以及特型與泛型、閉包、迭代器、集合、字符串與文本、輸入與輸出、並發、異步編程、宏等進階知識。
本書適合所有學習Rust的開發者,尤其適合系統程序員,從C++轉向Rust的程序員,以及具有C、C#、Jave、Python、JavaScript等其他編程語言基礎並希望學習Rust的程序員。
作者簡介
[美]吉姆·布兰迪(Jim Blandy),Mozilla Firefox工程师,Subversion版本控制系统初代设计者之一。拥有40多年编程经验,其中包括30多年自由软件开发经验,曾在GNU Emacs、GNU Debugger等项目上工作。
[美]贾森·奥伦多夫(Jason Orendorff),GitHub工程师,专注开发尚未公开的Rust项目,曾在Mozilla参与JavaScript引擎SpiderMonkey的开发。兴趣广泛,包括:语法学、烘焙、时间旅行,以及帮助人们理解复杂主题。
[美]莉奥诺拉·F. S. 廷德尔(Leonora F. S. Tindall),软件工程师、类型系统爱好者。她喜欢使用Rust等先进语言在一些关键领域构建健壮且适应性强的系统软件,特别是在医疗保健和数据所有权管理等领域。
【译者简介】
汪志成(@雪狼),Thoughtworks专家级咨询师、Google Developer Expert、25年码农。终身学习者,兴趣多元,涉猎广泛,目前专注研究Rust。
目錄大綱
目錄
專家推薦
譯者序
前言
中文版審讀致謝
第 1章 系統程序員也能享受美好 1
1.1 Rust為你負重前行 2
1.2 高效並行編程 3
1.3 性能毫不妥協 3
1.4 協作無邊無界 4
第 2章 Rust導覽 5
2.1 rustup與Cargo 6
2.2 Rust函數 8
2.3 編寫與運行單元測試 9
2.4 處理命令行參數 10
2.5 搭建Web服務器 13
2.6 並發 18
2.6.1 什麽是曼德博集 19
2.6.2 解析並配對命令行參數 22
2.6.3 從像素到復數的映射 24
2.6.4 繪制曼德博集 25
2.6.5 寫入圖像文件 26
2.6.6 並發版曼德博程序 27
2.6.7 運行曼德博繪圖器 32
2.6.8 大“安”無形 33
2.7 文件系統與命令行工具 33
2.7.1 命令行界面 34
2.7.2 讀寫文件 36
2.7.3 查找並替換 37
第3章 基本數據類型 39
3.1 固定寬度的數值類型 41
3.1.1 整型 42
3.1.2 檢查算法、回繞算法、飽和算法和溢出算法 45
3.1.3 浮點類型 46
3.2 布爾類型 48
3.3 字符 49
3.4 元組 50
3.5 指針類型 51
3.5.1 引用 52
3.5.2 Box 52
3.5.3 裸指針 53
3.6 數組、向量和切片 53
3.6.1 數組 53
3.6.2 向量 54
3.6.3 切片 57
3.7 字符串類型 58
3.7.1 字符串字面量 58
3.7.2 字節串 59
3.7.3 內存中的字符串 60
3.7.4 String 61
3.7.5 使用字符串 62
3.7.6 其他類似字符串的類型 62
3.8 類型別名 63
3.9 前路展望 63
第4章 所有權與移動 64
4.1 所有權 65
4.2 移動 70
4.2.1 更多移動類操作 74
4.2.2 移動與控制流 75
4.2.3 移動與索引內容 75
4.3 Copy類型:關於移動的例外情況 77
4.4 Rc與Arc:共享所有權 80
第5章 引用 83
5.1 對值的引用 84
5.2 使用引用 86
5.2.1 Rust引用與C++引用 87
5.2.2 對引用變量賦值 88
5.2.3 對引用進行引用 88
5.2.4 比較引用 89
5.2.5 引用永不為空 89
5.2.6 借用任意表達式結果值的引用 89
5.2.7 對切片和特型對象的引用 90
5.3 引用安全 90
5.3.1 借用局部變量 91
5.3.2 將引用作為函數參數 93
5.3.3 把引用傳給函數 95
5.3.4 返回引用 95
5.3.5 包含引用的結構體 96
5.3.6 不同的生命周期參數 98
5.3.7 省略生命周期參數 100
5.4 共享與可變 101
5.5 應對復雜對象關系 107
第6章 表達式 109
6.1 表達式語言 109
6.2 優先級與結合性 110
6.3 塊與分號 112
6.4 聲明 113
6.5 if與match 115
6.5.1 if let 117
6.5.2 循環 117
6.6 循環中的控制流 119
6.7 return表達式 120
6.8 為什麽Rust中會有loop 121
6.9 函數與方法調用 122
6.10 字段與元素 123
6.11 引用運算符 124
6.12 算術運算符、按位運算符、比較運算符和邏輯運算符 125
6.13 賦值 125
6.14 類型轉換 126
6.15 閉包 127
6.16 前路展望 127
第7章 錯誤處理 128
7.1 panic 128
7.1.1 展開調用棧 129
7.1.2 中止 130
7.2 Result 130
7.2.1 捕獲錯誤 131
7.2.2 Result類型別名 132
7.2.3 打印錯誤 132
7.2.4 傳播錯誤 134
7.2.5 處理多種Error類型 135
7.2.6 處理“不可能發生”的錯誤 136
7.2.7 忽略錯誤 138
7.2.8 處理main()中的錯誤 138
7.2.9 聲明自定義錯誤類型 139
7.2.10 為什麽是Result 140
第8章 crate與模塊 141
8.1 crate 141
8.1.1 版本 144
8.1.2 創建配置文件 145
8.2 模塊 145
8.2.1 嵌套模塊 146
8.2.2 單獨文件中的模塊 147
8.2.3 路徑與導入 149
8.2.4 標準庫預導入 152
8.2.5 公開use聲明 152
8.2.6 公開結構體字段 152
8.2.7 靜態變量與常量 153
8.3 將程序變成庫 153
8.4 src/bin目錄 155
8.5 屬性 156
8.6 測試與文檔 158
8.6.1 集成測試 161
8.6.2 文檔 161
8.6.3 文檔測試 163
8.7 指定依賴項 166
8.7.1 版本 166
8.7.2 Cargo.lock 167
8.8 將crate發布到crates.io 168
8.9 工作空間 170
8.10 更多好資源 170
第9章 結構體 172
9.1 具名字段型結構體 172
9.2 元組型結構體 175
9.3 單元型結構體 175
9.4 結構體佈局 176
9.5 用impl定義方法 177
9.5.1 以Box、Rc或Arc形式傳入self 179
9.5.2 類型關聯函數 179
9.6 關聯常量 180
9.7 泛型結構體 181
9.8 帶生命周期參數的泛型結構體 183
9.9 帶常量參數的泛型結構體 183
9.10 讓結構體類型派生自某些公共特型 185
9.11 內部可變性 186
第 10章 枚舉與模式 190
10.1 枚舉 191
10.1.1 帶數據的枚舉 193
10.1.2 內存中的枚舉 194
10.1.3 用枚舉表示富數據結構 194
10.1.4 泛型枚舉 196
10.2 模式 198
10.2.1 模式中的字面量、變量和通配符 201
10.2.2 元組型模式與結構體型模式 202
10.2.3 數組型模式與切片型模式 203
10.2.4 引用型模式 204
10.2.5 匹配守衛 206
10.2.6 匹配多種可能性 206
10.2.7 使用@模式綁定 207
10.2.8 模式能用在哪裡 207
10.2.9 填充二叉樹 209
10.3 大局觀 210
第 11章 特型與泛型 211
11.1 使用特型 213
11.1.1 特型對象 214
11.1.2 泛型函數與類型參數 215
11.1.3 使用哪一個 219
11.2 定義與實現特型 220
11.2.1 默認方法 221
11.2.2 特型與其他人的類型 222
11.2.3 特型中的Self 224
11.2.4 子特型 225
11.2.5 類型關聯函數 226
11.3 完全限定的方法調用 227
11.4 定義類型之間關系的特型 228
11.4.1 關聯類型(或迭代器的工作原理) 229
11.4.2 泛型特型(或運算符重載的工作原理) 231
11.4.3 impl Trait 232
11.4.4 關聯常量 234
11.5 逆向工程求限界 235
11.6 以特型為基礎 238
第 12章 運算符重載 239
12.1 算術運算符與按位運算符 240
12.1.1 一元運算符 242
12.1.2 二元運算符 243
12.1.3 復合賦值運算符 244
12.2 相等性比較 245
12.3 有序比較 247
12.4 Index與IndexMut 250
12.5 其他運算符 252
第 13章 實用工具特型 253
13.1 Drop 254
13.2 Sized 256
13.3 Clone 259
13.4 Copy 260
13.5 Deref與DerefMut 260
13.6 Default 263
13.7 AsRef與AsMut 264
13.8 Borrow與BorrowMut 266
13.9 From與Into 267
13.10 TryFrom與TryInto 270
13.11 ToOwned 271
13.12 Borrow與ToOwned的實際運用:謙卑的Cow 271
第 14章 閉包 273
14.1 捕獲變量 274
14.1.1 借用值的閉包 275
14.1.2 “竊取”值的閉包 275
14.2 函數與閉包的類型 277
14.3 閉包性能 279
14.4 閉包與安全 280
14.4.1 “殺死”閉包 280
14.4.2 FnOnce 281
14.4.3 FnMut 282
14.4.4 對閉包的Copy與Clone 284
14.5 回調 285
14.6 高效地使用閉包 288
第 15章 迭代器 290
15.1 Iterator特型與IntoIterator特型 291
15.2 創建迭代器 292
15.2.1 iter方法與iter_mut方法 293
15.2.2 IntoIterator的實現 293
15.2.3 from_fn與successors 295
15.2.4 drain方法 296
15.2.5 其他迭代器源 297
15.3 迭代器適配器 298
15.3.1 map與filter 298
15.3.2 filter_map與flat_map 300
15.3.3 flatten 302
15.3.4 take與take_while 304
15.3.5 skip與skip_while 305
15.3.6 peekable 305
15.3.7 fuse 306
15.3.8 可逆迭代器與rev 307
15.3.9 inspect 308
15.3.10 chain 309
15.3.11 enumerate 309
15.3.12 zip 310
15.3.13 by_ref 310
15.3.14 cloned與copied 311
15.3.15 cycle 312
15.4 消耗迭代器 313
15.4.1 簡單累加:count、sum和product 313
15.4.2 min與max 313
15.4.3 max_by與min_by 314
15.4.4 max_by_key與min_by_key 314
15.4.5 對條目序列進行比較 315
15.4.6 any與all 315
15.4.7 position、rposition和ExactSizeIterator 316
15.4.8 fold與rfold 316
15.4.9 try_fold與try_rfold 317
15.4.10 nth與nth_back 318
15.4.11 last 319
15.4.12 find、rfind和find_map 319
15.4.13 構建集合:collect與FromIterator 320
15.4.14 Extend特型 322
15.4.15 partition 322
15.4.16 for_each與try_for_each 323
15.5 實現自己的迭代器 324
第 16章 集合 328
16.1 概述 329
16.2 Vec
16.2.1 訪問元素 331
16.2.2 迭代 332
16.2.3 擴大向量與收縮向量 332
16.2.4 聯結 336
16.2.5 拆分 336
16.2.6 交換 339
16.2.7 填充 339
16.2.8 排序與搜索 339
16.2.9 比較切片 341
16.2.10 隨機元素 341
16.2.11 Rust中不存在失效型錯誤 342
16.3 VecDeque
16.4 BinaryHeap
16.5 HashMap
16.5.1 條目 349
16.5.2 對Map進行迭代 351
16.6 HashSet
16.6.1 對Set進行迭代 352
16.6.2 當相等的值不完全相同時 353
16.6.3 針對整個Set的運算 353
16.7 哈希 354
16.8 使用自定義哈希算法 355
16.9 在標準集合之外 357
第 17章 字符串與文本 358
17.1 一些Unicode背景知識 358
17.1.1 ASCII、Latin-1和Unicode 359
17.1.2 UTF-8編碼 359
17.1.3 文本方向性 361
17.2 字符(char) 361
17.2.1 字符分類 361
17.2.2 處理數字 362
17.2.3 字符大小寫轉換 363
17.2.4 與整數之間的轉換 364
17.3 String與str 364
17.3.1 創建字符串值 365
17.3.2 簡單探查 366
17.3.3 追加文本與插入文本 366
17.3.4 移除文本與替換文本 368
17.3.5 搜索與迭代的約定 368
17.3.6 搜索文本的模式 369
17.3.7 搜索與替換 370
17.3.8 遍歷文本 371
17.3.9 修剪 373
17.3.10 字符串的大小寫轉換 374
17.3.11 從字符串中解析出其他類型 374
17.3.12 將其他類型轉換為字符串 374
17.3.13 借用其他類似文本的類型 375
17.3.14 以UTF-8格式訪問文本 376
17.3.15 從UTF-8數據生成文本 376
17.3.16 推遲分配 377
17.3.17 把字符串當作泛型集合 379
17.4 格式化各種值 379
17.4.1 格式化文本值 380
17.4.2 格式化數值 381
17.4.3 格式化其他類型 383
17.4.4 格式化值以進行調試 383
17.4.5 格式化指針以進行調試 384
17.4.6 按索引或名稱引用參數 385
17.4.7 動態寬度與動態精度 386
17.4.8 格式化自己的類型 386
17.4.9 在自己的代碼中使用格式化語言 388
17.5 正則表達式 389
17.5.1 Regex的基本用法 389
17.5.2 惰性構建正則表達式值 390
17.6 規範化 391
17.6.1 規範化形式 392
17.6.2 unicode-normalization crate 393
第 18章 輸入與輸出 395
18.1 讀取器與寫入器 396
18.1.1 讀取器 397
18.1.2 緩沖讀取器 398
18.1.3 讀取行 399
18.1.4 收集行 401
18.1.5 寫入器 402
18.1.6 文件 403
18.1.7 尋址 404
18.1.8 其他讀取器與寫入器類型 404
18.1.9 二進制數據、壓縮和序列化 406
18.2 文件與目錄 407
18.2.1 OsStr與Path 408
18.2.2 Path與PathBuf的方法 409
18.2.3 訪問文件系統的函數 411
18.2.4 讀取目錄 412
18.2.5 特定於平臺的特性 413
18.3 網絡 414
第 19章 並發 417
19.1 分叉與合並並行 418
19.1.1 啟動與聯結 420
19.1.2 跨線程錯誤處理 422
19.1.3 跨線程共享不可變數據 422
19.1.4 rayon 424
19.1.5 重溫曼德博集 426
19.2 通道 427
19.2.1 發送值 429
19.2.2 接收值 431
19.2.3 運行管道 432
19.2.4 通道的特性與性能 434
19.2.5 線程安全:Send與Sync 435
19.2.6 絕大多數迭代器能通過管道傳給通道 437
19.2.7 除管道之外的用法 438
19.3 共享可變狀態 439
19.3.1 什麽是互斥鎖 439
19.3.2 Mutex
19.3.3 mut與互斥鎖 442
19.3.4 為什麽互斥鎖不是“銀彈” 443
19.3.5 死鎖 443
19.3.6 “中毒”的互斥鎖 444
19.3.7 使用互斥鎖的多消費者通道 444
19.3.8 讀/寫鎖(RwLock
19.3.9 條件變量(Condvar) 446
19.3.10 原子化類型 447
19.3.11 全局變量 448
19.4 在Rust中編寫並發代碼的一點兒經驗 451
第 20章 異步編程 452
20.1 從同步到異步 453
20.1.1 Future 455
20.1.2 異步函數與await表達式 456
20.1.3 從同步代碼調用異步函數:block_on 458
20.1.4 啟動異步任務 460
20.1.5 異步塊 464
20.1.6 從異步塊構建異步函數 466
20.1.7 在線程池中啟動異步任務 467
20.1.8 你的Future實現Send了嗎 467
20.1.9 長時間運行的計算:yield_now與spawn_blocking 470
20.1.10 對幾種異步設計進行比較 471
20.1.11 一個真正的異步HTTP客戶端 471
20.2 異步客戶端與服務器 472
20.2.1 Error類型與Result類型 474
20.2.2 協議 474
20.2.3 獲取用戶輸入:異步流 475
20.2.4 發送數據包 477
20.2.5 接收數據包:更多異步流 478
20.2.6 客戶端的main函數 480
20.2.7 服務器的main函數 481
20.2.8 處理聊天連接:異步互斥鎖 482
20.2.9 群組表:同步互斥鎖 484
20.2.10 聊天組:tokio的廣播通道 485
20.3 原始Future與執行器:Future什麽時候值得再次輪詢 488
20.3.1 調用喚醒器:spawn_blocking 489
20.3.2 實現block_on 491
20.4 固定(Pin) 493
20.4.1 Future生命周期的兩個階段 493
20.4.2 固定指針 496
20.4.3 Unpin特型 497
20.5 什麽時候要用異步代碼 498
第 21章 宏 500
21.1 宏基礎 501
21.1.1 宏展開的基礎 502
21.1.2 意外後果 503
21.1.3 重復 505
21.2 內置宏 507
21.3 調試宏 508
21.4 構建json!宏 509
21.4.1 片段類型 510
21.4.2 宏中的遞歸 513
21.4.3 將特型與宏一起使用 514
21.4.4 作用域界定與衛生宏 516
21.4.5 導入宏和導出宏 518
21.5 在匹配過程中避免語法錯誤 519
21.6 超越macro_rules! 520
第 22章 不安全代碼 522
22.1 不安全因素來自哪裡 523
22.2 不安全塊 524
22.3 示例:高效的ASCII字符串類型 525
22.4 不安全函數 527
22.5 不安全塊還是不安全函數 528
22.6 未定義行為 529
22.7 不安全特型 531
22.8 裸指針 532
22.8.1 安全地解引用裸指針 534
22.8.2 示例:RefWithFlag 535
22.8.3 可空指針 537
22.8.4 類型大小與對齊方式 537
22.8.5 指針運算 538
22.8.6 移動入和移動出內存 539
22.8.7 示例:GapBuffer 542
22.8.8 不安全代碼中的panic安全性 548
22.9 用聯合體重新解釋內存 549
22.10 匹配聯合體 551
22.11 借用聯合體 551
第 23章 外部函數 552
23.1 尋找共同的數據表示 552
23.2 聲明外部函數與變量 556
23.3 使用庫中的函數 557
23.4 libgit2的裸接口 560
23.5 libgit2的安全接口 566
23.6 結論 575
作者介紹 576
封面介紹 576