Rust Hello, Cargo!

2023-03-22 15:07 更新
ch01-03-hello-cargo.md
commit 0a5421ceb238357b3634fb75234eba4d1dad643c

Cargo 是 Rust 的構(gòu)建系統(tǒng)和包管理器。大多數(shù) Rustacean 們使用 Cargo 來管理他們的 Rust 項(xiàng)目,因?yàn)樗梢詾槟闾幚砗芏嗳蝿?wù),比如構(gòu)建代碼、下載依賴庫并編譯這些庫。(我們把代碼所需要的庫叫做 依賴dependencies))。

最簡單的 Rust 程序,比如我們剛剛編寫的,沒有任何依賴。如果使用 Cargo 來構(gòu)建 “Hello, world!” 項(xiàng)目,將只會用到 Cargo 構(gòu)建代碼的那部分功能。在編寫更復(fù)雜的 Rust 程序時(shí),你將添加依賴項(xiàng),如果使用 Cargo 啟動(dòng)項(xiàng)目,則添加依賴項(xiàng)將更容易。

由于絕大多數(shù) Rust 項(xiàng)目使用 Cargo,本書接下來的部分假設(shè)你也使用 Cargo。如果使用 “安裝” 部分介紹的官方安裝包的話,則自帶了 Cargo。如果通過其他方式安裝的話,可以在終端輸入如下命令檢查是否安裝了 Cargo:

$ cargo --version

如果你看到了版本號,說明已安裝!如果看到類似 command not found 的錯(cuò)誤,你應(yīng)該查看相應(yīng)安裝文檔以確定如何單獨(dú)安裝 Cargo。

使用 Cargo 創(chuàng)建項(xiàng)目

我們使用 Cargo 創(chuàng)建一個(gè)新項(xiàng)目,然后看看與上面的 “Hello, world!” 項(xiàng)目有什么不同?;氐?nbsp;projects 目錄(或者你存放代碼的目錄)。接著,可在任何操作系統(tǒng)下運(yùn)行以下命令:

$ cargo new hello_cargo
$ cd hello_cargo

第一行命令新建了名為 hello_cargo 的目錄和項(xiàng)目。我們將項(xiàng)目命名為 hello_cargo,同時(shí) Cargo 在一個(gè)同名目錄中創(chuàng)建項(xiàng)目文件。

進(jìn)入 hello_cargo 目錄并列出文件。將會看到 Cargo 生成了兩個(gè)文件和一個(gè)目錄:一個(gè) Cargo.toml 文件,一個(gè) src 目錄,以及位于 src 目錄中的 main.rs 文件。

這也會在 hello_cargo 目錄初始化了一個(gè) git 倉庫,以及一個(gè) .gitignore 文件。如果在一個(gè)已經(jīng)存在的 git 倉庫中運(yùn)行 cargo new,則這些 git 相關(guān)文件則不會生成;可以通過運(yùn)行 cargo new --vcs=git 來覆蓋這些行為。

注意:Git 是一個(gè)常用的版本控制系統(tǒng)(version control system, VCS)。可以通過 ?--vcs? 參數(shù)使 ?cargo new? 切換到其它版本控制系統(tǒng)(VCS),或者不使用 VCS。運(yùn)行 ?cargo new --help? 參看可用的選項(xiàng)。

請自行選用文本編輯器打開 Cargo.toml 文件。它應(yīng)該看起來如示例 1-2 所示:

文件名: Cargo.toml

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

示例 1-2: cargo new 命令生成的 Cargo.toml 的內(nèi)容

這個(gè)文件使用 TOML (Tom's Obvious, Minimal Language) 格式,這是 Cargo 配置文件的格式。

第一行,[package],是一個(gè)片段(section)標(biāo)題,表明下面的語句用來配置一個(gè)包。隨著我們在這個(gè)文件增加更多的信息,還將增加其他片段(section)。

接下來的三行設(shè)置了 Cargo 編譯程序所需的配置:項(xiàng)目的名稱、項(xiàng)目的版本以及要使用的 Rust 版本。附錄 E 會介紹 edition 的值。

最后一行,[dependencies],是羅列項(xiàng)目依賴的片段的開始。在 Rust 中,代碼包被稱為 crates。這個(gè)項(xiàng)目并不需要其他的 crate,不過在第二章的第一個(gè)項(xiàng)目會用到依賴,那時(shí)會用得上這個(gè)片段。

現(xiàn)在打開 src/main.rs 看看:

文件名: src/main.rs

fn main() {
    println!("Hello, world!");
}

Cargo 為你生成了一個(gè) “Hello, world!” 程序,正如我們之前編寫的示例 1-1!目前為止,我們的項(xiàng)目與 Cargo 生成項(xiàng)目的區(qū)別是 Cargo 將代碼放在 src 目錄,同時(shí)項(xiàng)目根目錄包含一個(gè) Cargo.toml 配置文件。

Cargo 期望源文件存放在 src 目錄中。項(xiàng)目根目錄只存放 README、license 信息、配置文件和其他跟代碼無關(guān)的文件。使用 Cargo 幫助你保持項(xiàng)目干凈整潔,一切井井有條。

如果沒有使用 Cargo 開始項(xiàng)目,比如我們創(chuàng)建的 Hello,world! 項(xiàng)目,可以將其轉(zhuǎn)化為一個(gè) Cargo 項(xiàng)目。將代碼放入 src 目錄,并創(chuàng)建一個(gè)合適的 Cargo.toml 文件。

構(gòu)建并運(yùn)行 Cargo 項(xiàng)目

現(xiàn)在讓我們看看通過 Cargo 構(gòu)建和運(yùn)行 “Hello, world!” 程序有什么不同!在 hello_cargo 目錄下,輸入下面的命令來構(gòu)建項(xiàng)目:

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

這個(gè)命令會創(chuàng)建一個(gè)可執(zhí)行文件 target/debug/hello_cargo (在 Windows 上是 target\debug\hello_cargo.exe),而不是放在目前目錄下。由于默認(rèn)的構(gòu)建方法是調(diào)試構(gòu)建(debug build),Cargo 會將可執(zhí)行文件放在名為 debug 的目錄中??梢酝ㄟ^這個(gè)命令運(yùn)行可執(zhí)行文件:

$ ./target/debug/hello_cargo # 或者在 Windows 下為 .\target\debug\hello_cargo.exe
Hello, world!

如果一切順利,終端上應(yīng)該會打印出 Hello, world!。首次運(yùn)行 cargo build 時(shí),也會使 Cargo 在項(xiàng)目根目錄創(chuàng)建一個(gè)新文件:Cargo.lock。這個(gè)文件記錄項(xiàng)目依賴的實(shí)際版本。這個(gè)項(xiàng)目并沒有依賴,所以其內(nèi)容比較少。你自己永遠(yuǎn)也不需要碰這個(gè)文件,讓 Cargo 處理它就行了。

我們剛剛使用 cargo build 構(gòu)建了項(xiàng)目,并使用 ./target/debug/hello_cargo 運(yùn)行了程序,也可以使用 cargo run 在一個(gè)命令中同時(shí)編譯并運(yùn)行生成的可執(zhí)行文件:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

比起要記得運(yùn)行 cargo build 之后再用可執(zhí)行文件的完整路徑來運(yùn)行程序,使用 cargo run 可以實(shí)現(xiàn)完全相同的效果,而且要方便得多,所以大多數(shù)開發(fā)者會使用 cargo run

注意這一次并沒有出現(xiàn)表明 Cargo 正在編譯 hello_cargo 的輸出。Cargo 發(fā)現(xiàn)文件并沒有被改變,所以它并沒有重新編譯,而是直接運(yùn)行了可執(zhí)行文件。如果修改了源文件的話,Cargo 會在運(yùn)行之前重新構(gòu)建項(xiàng)目,并會出現(xiàn)像這樣的輸出:

$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!

Cargo 還提供了一個(gè)叫 cargo check 的命令。該命令快速檢查代碼確保其可以編譯,但并不產(chǎn)生可執(zhí)行文件:

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

為什么你會不需要可執(zhí)行文件呢?通常 cargo check 要比 cargo build 快得多,因?yàn)樗÷粤松煽蓤?zhí)行文件的步驟。如果你在編寫代碼時(shí)持續(xù)的進(jìn)行檢查,cargo check 可以讓你快速了解現(xiàn)在的代碼能不能正常通過編譯!為此很多 Rustaceans 編寫代碼時(shí)定期運(yùn)行 cargo check 確保它們可以編譯。當(dāng)準(zhǔn)備好使用可執(zhí)行文件時(shí)才運(yùn)行 cargo build。

我們回顧下已學(xué)習(xí)的 Cargo 內(nèi)容:

  • 可以使用 ?cargo new? 創(chuàng)建項(xiàng)目。
  • 可以使用 ?cargo build? 構(gòu)建項(xiàng)目。
  • 可以使用 ?cargo run? 一步構(gòu)建并運(yùn)行項(xiàng)目。
  • 可以使用 ?cargo check? 在不生成二進(jìn)制文件的情況下構(gòu)建項(xiàng)目來檢查錯(cuò)誤。
  • 有別于將構(gòu)建結(jié)果放在與源碼相同的目錄,Cargo 會將其放到 target/debug 目錄。

使用 Cargo 的一個(gè)額外的優(yōu)點(diǎn)是,不管你使用什么操作系統(tǒng),其命令都是一樣的。所以從現(xiàn)在開始本書將不再為 Linux 和 macOS 以及 Windows 提供相應(yīng)的命令。

發(fā)布(release)構(gòu)建

當(dāng)項(xiàng)目最終準(zhǔn)備好發(fā)布時(shí),可以使用 cargo build --release 來優(yōu)化編譯項(xiàng)目。這會在 target/release 而不是 target/debug 下生成可執(zhí)行文件。這些優(yōu)化可以讓 Rust 代碼運(yùn)行的更快,不過啟用這些優(yōu)化也需要消耗更長的編譯時(shí)間。這也就是為什么會有兩種不同的配置:一種是為了開發(fā),你需要經(jīng)??焖僦匦聵?gòu)建;另一種是為用戶構(gòu)建最終程序,它們不會經(jīng)常重新構(gòu)建,并且希望程序運(yùn)行得越快越好。如果你在測試代碼的運(yùn)行時(shí)間,請確保運(yùn)行 cargo build --release 并使用 target/release 下的可執(zhí)行文件進(jìn)行測試。

把 Cargo 當(dāng)作習(xí)慣

對于簡單項(xiàng)目, Cargo 并不比 rustc 提供了更多的優(yōu)勢,不過隨著開發(fā)的深入,終將證明其價(jià)值。一旦程序壯大到由多個(gè)文件組成,亦或者是需要其他的依賴,讓 Cargo 協(xié)調(diào)構(gòu)建過程就會簡單得多。

即便 hello_cargo 項(xiàng)目十分簡單,它現(xiàn)在也使用了很多在你之后的 Rust 生涯將會用到的實(shí)用工具。其實(shí),要在任何已存在的項(xiàng)目上工作時(shí),可以使用如下命令通過 Git 檢出代碼,移動(dòng)到該項(xiàng)目目錄并構(gòu)建:

$ git clone example.org/someproject
$ cd someproject
$ cargo build

關(guān)于更多 Cargo 的信息,請查閱 其文檔。

總結(jié)

你已經(jīng)準(zhǔn)備好開啟 Rust 之旅了!在本章中,你學(xué)習(xí)了如何:

  • 使用 ?rustup ?安裝最新穩(wěn)定版的 Rust
  • 更新到新版的 Rust
  • 打開本地安裝的文檔
  • 直接通過 ?rustc ?編寫并運(yùn)行 Hello, world! 程序
  • 使用 Cargo 創(chuàng)建并運(yùn)行新項(xiàng)目

是時(shí)候通過構(gòu)建更實(shí)質(zhì)性的程序來熟悉讀寫 Rust 代碼了。所以在第二章我們會構(gòu)建一個(gè)猜猜看游戲程序。如果你更愿意從學(xué)習(xí) Rust 常用的編程概念開始,請閱讀第三章,接著再回到第二章。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號