跳轉到

4.1 Cargo:建構、執行與依賴管理#

Cargo 是 Rust 的靈魂#

Rust 的工具鏈只有一個核心入口:Cargo。它同時是建構工具、套件管理器、測試執行器、文件產生器——所有日常操作都是 cargo <動詞>。這是 Rust 開發體驗最好的部分之一:不需要學 Makefile、不需要選建構系統。

日常四個指令#

cargo new my-app          # 建立新專案(可執行檔)
cargo new --lib my-lib    # 建立函式庫專案

cargo build               # 編譯(debug 模式,輸出到 target/debug/)
cargo run                 # 編譯 + 執行
cargo check               # 只檢查能不能編譯,不產出執行檔——最快
cargo test                # 執行所有測試(第六章)

cargo check 是開發時最常用的:只做型別與借用檢查、不連結執行檔,速度比 build 快很多。習慣的開發循環是:改程式 → cargo check → 全部通過 → cargo run / cargo test。

Debug 與 Release 模式#

cargo build               # debug 模式:編譯快、含除錯資訊、未最佳化
cargo build --release     # release 模式:最佳化、編譯慢、執行快數十倍
debug(預設) release
編譯時間 快 慢
執行速度 慢 快很多(10-100 倍)
輸出位置 target/debug/ target/release/
用途 日常開發、除錯 正式部署、效能測試

重要:效能問題要在 release 模式下量測。debug 模式慢幾十倍,在 debug 下做 benchmark 會得到完全錯誤的結論。

依賴管理:Cargo.toml#

Cargo.toml 是專案的設定檔(像 package.json):

[package]
name = "my-app"
version = "0.1.0"
edition = "2021"

[dependencies]
serde = "1.0"           # 語意化版本:相容 1.x.x 的最新版
tokio = { version = "1", features = ["full"] }
anyhow = "1"

加入依賴只需編輯 Cargo.toml 後 cargo build——依賴會自動從 crates.io(Rust 的官方套件倉庫)下載。

cargo add serde          # 不用手編輯,直接加依賴(推薦)
cargo update             # 更新依賴到相容範圍內的最新版

Cargo.lock:鎖定確切版本#

cargo build 會產生 Cargo.lock,記錄每個依賴的確切版本:

  • 執行檔專案:Cargo.lock 進 Git——每次建構的依賴版本完全一致
  • 函式庫專案:慣例上不進 Git(讓使用者決定版本)

這是「可重現建構(reproducible build)」的基礎:同一份 lock 檔,任何機器、任何時間建出來的依賴版本都一樣。

常用 Cargo 指令速查#

cargo check                  # 快速檢查(開發循環用)
cargo build --release        # 正式建構
cargo run --release          # 正式模式執行
cargo test                   # 跑測試
cargo add <crate>            # 加依賴
cargo doc --open             # 產生並打開 API 文件
cargo clean                  # 清除 target/(磁碟滿了再說)

本章小結#

  • 一切日常操作都是 cargo <動詞>
  • 開發循環:cargo check(最快)→ cargo run / cargo test
  • 效能要在 --release 下量測,debug 慢數十倍
  • 依賴寫進 Cargo.toml,確切版本鎖在 Cargo.lock(執行檔專案進 Git)
  • cargo add 加依賴、cargo doc --open 看文件

想一想#

  1. 為什麼開發時用 cargo check 而不是每次都 cargo build?
  2. 為什麼效能測試必須在 release 模式下做?debug 模式會量出什麼錯誤結論?
  3. Cargo.lock 為什麼要進 Git?不進會發生什麼?