Rust-01 啟航

trickyrat發表於2023-01-04

安裝

所謂工欲善其事必先利其器,我們學習Rust當然需要安裝Rust。我們可以從Rust官網下載rustup工具進行rust的安裝。安裝完成後,我們在命令列中輸入rustc --version便可以檢視我們所安裝rust的版本。
rustc 版本命令截圖

筆者推薦在Windows平臺使用PowerShell CoreWindows Terminal

Rust相關命令

安裝好 rust 後,我們需要了解幾個東西

rustc

rustc是 rust 的編譯器,負責將 rs 檔案原始碼編譯到可執行檔案或者庫的二進位制程式碼

rustup

rustup是 rust 的升級管理工具,負責升級 rust 的版本,常用命令rustup update用來升級 rust

cargo

一般都不直接使用rustc來直接編譯 rs 檔案,而是選擇cargocargo是 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 資訊並且沒有最佳化的程式碼,可以得到下圖所示內容

cargo build的命令截圖

而新增--release引數後,則會生成不帶 debug 資訊且最佳化後的程式碼,如下圖所示(這一般是在正式釋出時使用)

cargo build --release的命令截圖

執行cargo build命令後會在專案目錄下生成一個 target 資料夾,target 資料夾中的內容就是編譯生成的結果。根據cargo build後面新增的引數會生成兩個資料夾,即releasedebug

cargo build 生成資料夾截圖

也可以直接執行cargo run命令直接執行專案,這個命令就相當於cargo build && ./debug/hello-world.exe先編譯專案然後再執行編譯後的可執行檔案。和cargo build一樣預設是生成 debug 程式碼,帶上--release引數後則是 release 程式碼。
下圖是cargo run所顯示資訊

cargo run預設截圖

下圖是cargo run --release所顯示資訊

cargo run release截圖

依賴項

在專案資料夾中找到Cargo.toml檔案,這個檔案便是 Rust 專案的依賴項配置檔案
cargo.toml配置檔案截圖在這個檔案裡對專案進行配置,比如我現在需要使用隨機數,那麼我只需要在[dependencies]下面新增rand = "0.8.3",然後專案執行時,cargo 會自己進行依賴還原,將詳細的包寫入Cargo.lock檔案中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官網

相關文章