Rust權威指南(第2版) The Rust Programming Language, 2/e
毛靖凱
- 出版商: 電子工業
- 出版日期: 2025-02-01
- 定價: $1,008
- 售價: 8.5 折 $857
- 語言: 簡體中文
- 頁數: 704
- ISBN: 7121494736
- ISBN-13: 9787121494734
-
相關分類:
Rust 語言、程式語言
- 此書翻譯自: The Rust Programming Language, 2/e (Paperback)
下單後立即進貨 (約4週~6週)
商品描述
本書由Rust核心開發團隊編寫而成,由淺入深地探討了Rust語言的方方面面。從學習函數、選擇數據結構及綁定變量入手,逐步介紹所有權、trait、生命周期、安全保證等高級概念,模式匹配、錯誤處理、包管理、函數式特性、並發機制等實用工具,以及兩個完整的項目開發實戰案例。 作為開源的系統級編程語言,Rust可以幫助你編寫出更為快速且更為可靠的軟件,在給予開發者底層控制能力的同時,通過深思熟慮的工程設計避免了傳統語言帶來的諸多麻煩。
目錄大綱
1 入門指南 1
安裝 1
在Linux或macOS環境中安裝Rust 2
在Windows環境中安裝Rust 3
常見問題 3
更新與卸載 4
本地文檔 5
Hello, world! 5
創建一個文件夾 5
編寫並運行一個Rust程序 6
Rust程序剖析 7
編譯與運行是兩個不同的步驟 8
Hello, Cargo! 10
使用Cargo創建一個項目 10
使用Cargo構建和運行項目 13
以Release模式進行構建 15
學會習慣Cargo 15
總結 16
2 編寫一個猜數游戲 17
創建一個新的項目 17
處理一次猜測 19
使用變量存儲值 20
獲得用戶的輸入 21
使用Result類型處理可能失敗的情況 22
通過println!中的占位符輸出對應的值 23
測試第一部分 24
生成一個保密數字 24
借助包獲得更多功能 25
生成一個隨機數 28
比較猜測數字與保密數字 31
使用循環實現多次猜測 35
在猜測成功時優雅地退出 37
處理非法輸入 37
總結 40
3 通用編程概念 41
變量與可變性 42
常量 44
隱藏 45
數據類型 47
標量類型 48
復合類型 53
函數 57
參數 59
語句和表達式 60
函數的返回值 62
註釋 65
控制流 66
if表達式 66
使用循環重復執行代碼 70
總結 77
4 認識所有權 78
什麽是所有權 78
所有權規則 81
變量作用域 81
String類型 82
內存與分配 83
所有權與函數 90
返回值與作用域 91
引用與借用 93
可變引用 95
懸垂引用 99
引用的規則 101
切片類型 101
字符串切片 103
其他類型的切片 108
總結 109
5 使用結構體組織相關聯的數據 110
定義並實例化結構體 110
使用簡化版的字段初始化方法 113
使用結構體更新語法,基於其他實例來創建新實例 113
使用不需要對字段命名的元組結構體來創建不同的類型 115
沒有任何字段的單元結構體 116
一個使用結構體的示例程序 118
使用元組重構代碼 119
使用結構體重構代碼:增加有意義的描述信息 120
通過派生trait增加實用功能 121
方法 125
定義方法 125
帶有更多參數的方法 129
關聯函數 130
多個impl塊 131
總結 132
6 枚舉與模式匹配 133
定義枚舉 133
枚舉值 134
Option枚舉及其在空值處理方面的優勢 139
控制流結構match 143
綁定值的模式 145
匹配Option<T> 146
匹配必須窮舉所有的可能性 148
通配模式及_占位符 149
簡單控制流if let 151
總結 153
7 使用包、單元包和模塊管理日漸復雜的項目 154
包與單元包 155
通過定義模塊來控製作用域及私有性 160
用於在模塊樹中指明條目的路徑 162
使用pub關鍵字來暴露路徑 165
從super關鍵字開始構造相對路徑 169
將結構體或枚舉聲明為公共的 170
使用use關鍵字將路徑導入作用域 172
創建use路徑時的慣用方式 174
使用as關鍵字來提供新的名稱 175
使用pub use重導出名稱 176
使用外部包 177
使用嵌套路徑來清理眾多的use語句 178
通配符 179
將模塊拆分為不同的文件 180
總結 182
8 通用集合類型 184
使用動態數組存儲多個值 185
創建動態數組 185
更新動態數組 186
讀取動態數組中的元素 186
遍歷動態數組中的值 189
使用枚舉存儲多個類型的值 190
在銷毀動態數組時也會銷毀其中的元素 191
使用字符串存儲UTF-8編碼的文本 192
字符串是什麽 192
創建一個新的字符串 193
更新字符串 194
索引字符串 197
字符串切片 200
遍歷字符串的方法 201
字符串的確沒那麽簡單 202
在哈希映射中存儲鍵值對 202
創建一個新的哈希映射 203
訪問哈希映射中的值 203
哈希映射與所有權 205
更新哈希映射 205
哈希函數 208
總結 208
9 錯誤處理 210
不可恢復錯誤與panic! 211
可恢復錯誤與Result 215
匹配不同的錯誤 217
傳播錯誤 221
要不要使用panic! 229
示例、原型代碼和測試 229
當你比編譯器擁有更多信息時 230
錯誤處理指導原則 230
創建自定義類型進行有效性驗證 232
總結 235
10 泛型、trait與生命周期 236
通過將代碼提取為函數來減少重復工作 237
泛型數據類型 240
在函數定義中 240
在結構體定義中 243
在枚舉定義中 245
在方法定義中 246
泛型代碼的性能問題 249
trait:定義共享行為 250
定義trait 250
為類型實現trait 251
默認實現 254
使用trait作為參數 256
返回實現了trait的類型 259
使用trait約束有條件地實現方法 260
使用生命周期保證引用的有效性 262
使用生命周期來避免懸垂引用 262
借用檢查器 264
函數中的泛型生命周期 265
生命周期標註語法 267
函數簽名中的生命周期標註 267
深入理解生命周期 271
結構體定義中的生命周期標註 272
生命周期省略 273
方法定義中的生命周期標註 276
靜態生命周期 277
同時使用泛型參數、trait約束與生命周期 278
總結 279
11 編寫自動化測試 280
如何編寫測試 281
測試函數的構成 281
使用assert!宏檢查結果 286
使用assert_eq!和assert_ne!宏判斷相等性 290
添加自定義的錯誤提示信息 293
使用should_panic檢查panic 295
使用Result<T, E>編寫測試 300
控制測試的運行方式 301
並行或串行地運行測試 301
顯示函數輸出 302
運行部分特定名稱的測試 304
通過顯式指定來忽略某些測試 307
測試的組織結構 308
單元測試 309
集成測試 311
總結 316
12 I/O項目:編寫一個命令行程序 317
接收命令行參數 318
讀取參數值 319
將參數值存入變量中 321
讀取文件 322
重構代碼以增強模塊化程度和錯誤處理能力 324
二進制項目的關註點分離 325
修正錯誤處理邏輯 330
從main中分離邏輯 334
將代碼分離為獨立的代碼包 337
使用測試驅動開發編寫庫功能 339
編寫一個會失敗的測試 340
編寫可以通過測試的代碼 343
處理環境變量 347
為不區分大小寫的search函數編寫一個會失敗的測試 347
實現search_case_insensitive函數 349
將錯誤提示信息打印到標準錯誤流而不是標準輸出流 354
確認錯誤被寫到了哪裡 354
將錯誤提示信息打印到標準錯誤流 355
總結 356
13 函數式語言特性:迭代器與閉包 357
閉包:能夠捕獲環境的匿名函數 358
使用閉包捕獲環境 358
閉包的類型推斷和類型標註 361
捕獲引用或移動所有權 363
將捕獲的值移出閉包及Fn系列trait 366
使用迭代器處理元素序列 371
Iterator trait和next方法 372
消耗迭代器的方法 373
生成其他迭代器的方法 374
使用閉包捕獲環境 376
改進I/O項目 378
使用迭代器代替clone 378
使用迭代器適配器讓代碼更加清晰 382
在循環與迭代器之間做出選擇 383
比較循環和迭代器的性能 383
總結 386
14 進一步認識Cargo及crates.io 387
使用發布配置定製構建 388
將包發布到crates.io平臺 389
編寫有用的文檔註釋 390
使用pub use導出合適的公共API 393
創建crates.io賬戶 398
為包添加元數據 398
發布到crates.io 400
發布已有包的新版本 401
使用cargo yank命令從crates.io上撤回版本 401
Cargo工作空間 402
創建工作空間 402
在工作空間中創建第二個包 404
使用cargo install安裝二進制文件 409
使用自定義命令擴展Cargo的功能 410
總結 411
15 智能指針 412
使用Box<T>在堆上分配數據 414
使用Box<T>在堆上存儲數據 414
使用裝箱定義遞歸類型 415
通過Deref trait將智能指針視作常規引用 421
跳轉到指針指向的值 421
把Box<T>當成引用來操作 422
定義我們自己的智能指針 423
實現Deref trait 424
函數和方法的隱式解引用轉換 426
解引用轉換與可變性 427
借助Drop trait在清理時運行代碼 428
基於引用計數的智能指針Rc<T> 433
使用Rc<T>共享數據 433
克隆Rc<T>會增加引用計數 436
RefCell<T>和內部可變性模式 438
使用RefCell<T>在運行時檢查借用規則 438
內部可變性:可變地借用一個不可變的值 440
結合使用Rc<T>和RefCell<T>來實現擁有多重所有權的可變量據 448
循環引用會造成內存泄漏 450
創建循環引用 450
使用Weak<T>代替Rc<T>來避免循環引用 454
總結 460
16 無畏並發 461
使用線程同時運行代碼 462
使用spawn創建新線程 463
使用join句柄等待所有線程結束 465
在線程中使用move閉包 467
使用消息傳遞在線程間轉移數據 471
通道和所有權轉移 474
發送多個值並觀察接收者的等待過程 476
通過克隆發送者創建多個生產者 477
共享狀態的並發 479
互斥體一次只允許一個線程訪問數據 479
RefCell<T>/Rc<T>和Mutex<T>/Arc<T>之間的相似性 486
使用Send trait和Sync trait對並發進行擴展 487
允許線程間轉移所有權的Send trait 487
允許多個線程同時訪問的Sync trait 488
手動實現Send和Sync是不安全的 488
總結 489
17 Rust的面向對象編程特性 490
面向對象語言的特性 490
對象包含數據和行為 491
封裝實現細節 491
作為類型系統和代碼共享機制的繼承 493
使用trait對象存儲不同類型的值 495
為共有行為定義一個trait 496
實現trait 498
trait對象會執行動態派發 502
實現一種面向對象的設計模式 502
定義Post並創建一個處於草稿狀態的新實例 505
存儲文章內容的文本 506
確保草稿的可讀內容為空 507
請求審批文章並改變其狀態 507
添加approve方法來改變content的行為 509
狀態模式的權衡取捨 513
總結 518
18 模式與匹配 520
所有可以使用模式的場合 521
match分支 521
if let條件表達式 522
while let條件循環 524
for循環 524
let語句 525
函數的參數 527
可失敗性:模式是否會匹配失敗 528
模式語法 531
匹配字面量 531
匹配命名變量 531
多重模式 533
使用“..=”匹配區間值 533
通過解構分解值 534
忽略模式中的值 540
使用匹配守衛添加額外條件 545
@綁定 548
總結 549
19 高級特性 550
不安全Rust 551
不安全超能力 551
解引用裸指針 553
調用不安全的函數或方法 555
訪問或修改可變靜態變量 561
實現不安全trait 563
訪問聯合體中的字段 564
使用不安全代碼的時機 564
高級trait 564
關聯類型 565
默認泛型參數和運算符重載 566
消除同名方法在調用時的歧義 569
使用超trait 574
使用newtype模式在外部類型上實現外部trait 576
高級類型 578
使用newtype模式實現類型安全與抽象 578
使用類型別名創建同義類型 579
永不返回的never類型 582
動態大小類型和Sized trait 584
高級函數與閉包 586
函數指針 586
返回閉包 589
宏 590
宏與函數之間的區別 591
用於通用元編程的macro_rules!聲明宏 591
基於屬性創建代碼的過程宏 594
如何編寫一個自定義派生宏 595
屬性宏 601
函數宏 602
總結 603
20 最後的項目:構建多線程Web服務器 604
構建單線程Web服務器 605
監聽TCP連接 606
讀取請求 608
仔細觀察HTTP請求 611
編寫響應 612
返回真正的HTML文件 613
驗證請求的合法性並有選擇地響應 615
少許重構 618
把單線程服務器修改為多線程服務器 619
模擬一個慢請求 620
使用線程池改進吞吐量 621
優雅地停機與清理 642
為ThreadPool實現Drop trait 642
通知線程停止監聽任務 645
總結 650
附錄A 關鍵字 651
附錄B 運算符和符號 656
附錄C 可派生 trait 663
附錄D 有用的開發工具 669
附錄E 階段性版本 673