安裝
所謂工欲善其事必先利其器,我們學習Rust當然需要安裝Rust。我們可以從Rust官網下載rustup
工具進行rust的安裝。安裝完成後,我們在命令列中輸入rustc --version
便可以檢視我們所安裝rust的版本。
筆者推薦在Windows平臺使用PowerShell Core和Windows Terminal
Rust相關命令
安裝好 rust 後,我們需要了解幾個東西
rustc
rustc
是 rust 的編譯器,負責將 rs 檔案原始碼編譯到可執行檔案或者庫的二進位制程式碼
rustup
rustup
是 rust 的升級管理工具,負責升級 rust 的版本,常用命令rustup update
用來升級 rust
cargo
一般都不直接使用rustc
來直接編譯 rs 檔案,而是選擇cargo
。 cargo
是 Rust 的包管理器,可以用來建立專案、安裝依賴、型別檢測、編譯、執行以及測試專案等功能。cargo是一個功能強大的工具。
cargo run能夠自動化呼叫
rustc` 對 rs 檔案進行編譯產出二進位制檔案並執行二進位制檔案。
常用cargo命令
命令 | 說明 | 示例 |
---|---|---|
cargo new | 建立專案,預設建立 binary 專案,新增引數可以選擇 lib 和 bin 兩種專案 | cargo new hello --lib(預設--bin) |
cargo check | 型別檢測 | cargo check |
cargo build | 編譯專案 | cargo build [--release] |
cargo run | 執行專案,可以帶引數 | cargo run [--release] |
cargo test | 對專案進行單元測試 | cargo test |
詳細的說明可以檢視官方文件。
IDE
現在能夠開發 rust 的工具已經有很多了,比如 Jetbrains 家的Clion(需要新增 rust 外掛)或者 Microsoft家的VS Code(需要安裝rust-analyzer擴充套件)
Hello World!
既然已經有了 rust 的執行環境,那麼我們便開始建立第一個 rust 專案。使用cargo new hello-world
命令建立一個名為hello-world
的專案,然後cd hello-world
進入專案目錄後可以看到專案的結構
C:.
│ .gitignore
│ Cargo.toml
│
└─src
main.rs
專案根路徑會有一個Cargo.toml
和一個src\main.rs
,其中Cargo.toml
檔案是負責配置 cargo 和專案依賴項,main.rs 檔案則是程式的入口點,main.rs 裡的程式碼
fn main() {
println!("Hello, world!");
}
簡單易懂,關鍵字fn
用來宣告這是一個無返回值名稱為main
的 function,然後函式體內呼叫 rust 的輸出宏println!
輸出了Hello, world!
在 Rust 中所有的函式呼叫都是必須有返回值的表示式,無返回值的返回一個空的 tuple 表示或者省略不寫。
fn foo() -> () {}
// 二者等效
fn foo() {}
我們執行cargo build
,對專案進行編譯,預設情況下是生成帶有 debug 資訊並且沒有最佳化的程式碼,可以得到下圖所示內容
而新增--release
引數後,則會生成不帶 debug 資訊且最佳化後的程式碼,如下圖所示(這一般是在正式釋出時使用)
執行cargo build
命令後會在專案目錄下生成一個 target 資料夾,target 資料夾中的內容就是編譯生成的結果。根據cargo build
後面新增的引數會生成兩個資料夾,即release
和debug
。
也可以直接執行cargo run
命令直接執行專案,這個命令就相當於cargo build && ./debug/hello-world.exe
先編譯專案然後再執行編譯後的可執行檔案。和cargo build
一樣預設是生成 debug 程式碼,帶上--release
引數後則是 release 程式碼。
下圖是cargo run
所顯示資訊
下圖是cargo run --release
所顯示資訊
依賴項
在專案資料夾中找到Cargo.toml
檔案,這個檔案便是 Rust 專案的依賴項配置檔案
在這個檔案裡對專案進行配置,比如我現在需要使用隨機數,那麼我只需要在[dependencies]
下面新增rand = "0.8.3"
,然後專案執行時,cargo 會自己進行依賴還原,將詳細的包寫入Cargo.lock
檔案中並且會自動去解析引入包的依賴,這和 npm 相似。
猜數字遊戲
我們現在可以寫一個小遊戲來走一遍 Rust 專案建立到執行的流程
使用cargo new
建立一個新的專案,然後在Cargo.toml
檔案中的[dependencies]
下面新增rand = "0.8.3"
開啟main.rs
,並新增以下程式碼
use rand::Rng;
use std::cmp::Ordering;
use std::io;
fn guess() {
println!("Guess the number!");
let secret_number = rand::thread_rng().gen_range(1..101);
loop {
println!("Please input your guess.");
let mut buffer = String::new();
io::stdin()
.read_line(&mut buffer)
.expect("Failed to read line!");
let number: i32 = match buffer.trim().parse() {
Ok(num) => num,
Err(_) => continue,
};
match number.cmp(&secret_number) {
Ordering::Less => println!("Too small!"),
Ordering::Greater => println!("Too big!"),
Ordering::Equal => {
println!("You win!");
break;
}
}
}
}
fn main() {
guess();
}
這些程式碼也很容易理解。use std::io;
、use std::cmp::Ordering;
和use rand::Rng;
分別引入我們需要的模組。
std::io
用來獲取輸入的數字,std::cmp::Ordering
用來比較輸入的數字和隨機數的大小,rand::Rng
用來生成隨機數。
然後我們宣告瞭一個無引數和無返回值的函式 guess
。函式里主要是輸出一行提示使用者輸入的提示資訊和生成範圍在[1,101)的隨機整數,並根據使用者輸入的數字與隨機數進行比較,直到使用者猜測數字等於隨機數字後結束程式。
我們需要處理使用者的輸入,在 rust 中使用io::stdin().read_line()
從標準輸入流中獲取使用者的輸入,因為read_line()
返回的是Result<usize>
,在 rust 中Result<T>
都可以使用 match(模式匹配)來對結果進行處理。loop
在 rust 中是開啟一個無線迴圈,根據內部的 break 來跳出迴圈,這裡我們根據使用者輸入的數字和產生的隨機數字比較結果作為是否結束迴圈的條件。在 rust 中,我們需要著重的學習match
模式匹配,這裡number.cmp
返回一個Ordering
,我們可以根據不同的結果進行不同處理,這和 if 條件判斷類似,但是程式碼的可讀性變高了,更利於理解,在 rust 中儘量使用模式匹配來進行邏輯判斷以便減少 bug。main
函式就是簡單地呼叫guess
函式。
使用cargo run
後,我們會得到以下資訊
總結
至此,我們瞭解了 rust 的安裝和各種命令以及建立並執行一個 rust 專案的所有流程。
引用
部分內容和程式碼參考Rust官網