Rust是一種程式語言,可以幫助您開發出更快、更可靠的軟體。直覺又易懂的高階程式語言(如Golang、Python、JavaScript、PHP)和高效卻難懂而相對低階的程式語言(如C、C++),在設計程式時,這兩者經常會被區分開來。好比說,現在要開發一個網站,通常人們會選擇使用Golang、PHP等專門開發伺服器程式的程式語言,而非選擇C或C++這樣的程式語言;但如果現在是要開發一個講究效能的資料庫,通常人們會選擇使用C或C++。而如今,Rust將要挑戰這項傳統!



透過吸收多種程式語言的優點和多位程式開發者的經驗,Rust提供出另一項選擇,那就是可以利用高階語言的特性,來做出具有低階語言效能和控制性的程式。

那麼Rust究竟適合用在什麼地方?

Rust適合各式各樣的人來使用,無論在應用層或底層程式上都派得上用場,對於開發者來說,使用愈低階的程式語言雖然可以增加程式效能,但通常也會愈容易產生出難以捕捉的Bug,而如果使用Rust程式語言的話,則可以在程式編譯階段就找出大部份的可能會出現的問題,且能讓最後的產品也能保有低階語言的效能。對於開發者團隊來說,甚至還能夠統一應用層和底層的程式語言。對於學生來說,Rust可觸及底層程式的特性能夠使他們加深對電腦系統的了解,並且也不用花費時間在學習處理程式安全性不佳所造成的各種不穩定的問題,而能真正地專注在全面了解程式的概念上。

此外,Rust也提供了一些現代化的開發工具:

  • Cargo:程式碼專案相依性管理和建置工具。
  • Rustfmt:確保每位開發者程式碼風格的一致性。
  • Rust Language Server(RLS):提供各個IDE或是編輯器一個標準介面來處理程式碼自動補全、重新格式化等功能。

安裝與設定Rust開發環境

學習Rust的第一步驟當然是要先弄好Rust的開發環境啦!底下將分別介紹在Linux作業系統和Windows作業系統上,安裝與設定Rust開發環境的作法。

rustup

Rust大概每六個星期就會有新版本出現,為了方便管理Rust,可以使用rustup指令工具來安裝和管理不同版本的Rust。

安裝rustup(Linux作業系統)

由於Rust還是會用到C/C++語言的東西,所以最好還是把C/C++的基本開發工具先安裝起來,以免Rust程式編譯失敗。

基於Debian的Linux發行版可以用以下指令來安裝:

sudo apt install build-essential

紅帽系的Linux發行版可以用以下指令來安裝:

sudo dnf groupinstall "Development Tools" "Development Libraries"

然後執行以下指令來用rustup安裝Rust的開發工具:

curl -fsSL https://sh.rustup.rs | sh -s -- -y

rust-introduction

接著要重新登入shell或是使用以下指令直接套用新的環境設定:

source "$HOME/.cargo/env"

如此一來Rust和Rust包含的相關工具都已經安裝並且設定完畢,可以直接在終端機上使用了!

安裝rustup(Windows作業系統)

使透過以下連結到rustup的官方網站,下載rustup‑init.exe安裝檔。

接著執行rustup‑init.exe安裝檔。安裝檔可能會提示說需要微軟的Visual C++ Build Tools。

rust-introduction

如下圖,照著指示安裝即可。

rust-introduction

rust-introduction

rust-introduction

如果「Visual C++ Build Tools」有安裝成功,rustup‑init.exe就不會再出現需要安裝「Visual C++ Build Tools」的訊息了。

rust-introduction

選擇Proceed with installation就能開始安裝。將Rust和Rust包含的相關工具安裝好之後,重新啟動命令提示字元就可以開始使用。

rust-introduction

rust-introduction

使用rustup

切換Rust版本:

rustup default <toolchain>

例如切換成nightly:

rustup default nightly

例如切換成最新的穩定版:

rustup default stable

例如切換成指定版本:

rustup default 1.72.1

升級Rust版本:

rustup update

移除Rust:

rustup self uninstall

Hello World

安裝與設定完Rust開發環境之後,就可以開始撰寫Rust程式啦!依照慣例,我們來寫寫看在學習程式語言時總會寫的第一支程式──「Hello World」。「Hello World」是一支非常簡單的小程式,執行這支程式之後,螢幕上就會印出Hello, world!這幾個字。

建立專案目錄

一般來說,在開始撰寫Rust程式時,會使用cargo指令工具來建立出Rust專案,但由於「Hello World」是我們第一支的程式,我們傾向用最單純的方式完成它,所以在此先不使用cargo

首先,建立並開啟一個用來存放Rust專案的目錄hello_world。如果是Linux作業系統的環境,可以使用以下指令在家目錄中的rust_projects目錄中建立出hello_world目錄,並將目前工作目錄移動到hello_world目錄:

mkdir -p ~/RustProjects/hello_world && cd ~/RustProjects/hello_world

建立Rust原始碼檔案

接著建立出一個純文字檔案,檔名取為main.rs。雖然這邊的檔案名稱使用main.rs之外的其它名稱也是可以,但在使用Cargo管理Rust程式專案時,程式進入點所使用的檔案名稱就是main.rs,我們需要習慣一下這樣的檔案結構。如果是Linux作業系統的環境,可以使用以下指令來建立出一個空的檔案:

touch main.rs

接著使用文字編輯器開啟剛才建立的main.rs,並輸入以下程式碼:

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

存檔之後,就可以使用Rust的編譯器進行編譯了。

用rustc編譯Rust程式

一般來說,我們會透過「cargo」來編譯Rust專案,而非直接使用「rustc」,也是一樣的理由,由於「Hello World」是我們第一支的程式,我們傾向用最單純的方式完成它,所以在此先不使用「cargo」。

rustc是Rust的編譯器程式,若要編譯剛才寫好的main.rs,可以使用以下指令:

rustc main.rs

rust-introduction

如果編譯成功,編譯器不會印出任何訊息,且會在目前的工作目錄中,建立出檔名為main(Windows作業系統的話則為main.exe)的執行檔,這樣就完成Rust程式的編譯了。

執行Rust程式

直接在終端機執行這個編譯出來的執行檔。Linux作業系統的話可以輸入以下指令來執行main

./main

執行結果:

Hello, world!

rust-introduction

Hello World程式碼解析

我們來看以下剛才寫的(或是複製貼上的)Rust程式究竟是在做什麼。先看一下程式碼的第一行和第三行:

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

這樣的結構定義了一個名叫main的函數。將函數命名為main是有特別的意義的,那就是程式在一開始執行的時候,會先執行這個main函數,也就是說,這個函數是Rust程式的程式進入點。第一行在左大括號{之前我們定義了這個函數的簽名(signature),由於小括號()內並沒有定義任何參數,且小括號的右邊也沒有撰寫->來定義函數的回傳型別,因此在使用這個main函數時不用輸入任何參數,而且它也不會回傳任何資料。

接著來說明一下大括號{}的意義。這組緊接在函數簽名之後的大括號,定義了該函數的主體(body),也就是該函數被呼叫的時候要執行的敘述(statement)。

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

main函數中,我們加入了這行敘述println!("Hello, world!");。這行程式的目的就是將Hello, world!文字印出在螢幕上,並且進行換行的動作。如果您有學過其他語言,或許對printlog等等的函數已經足夠熟悉,然而,在這個Hello World程式中使用的println!卻並不是屬於這類的函數(請注意println後面還有一個驚嘆號!,這並不是打錯字哦!),而是「巨集(macro)」。有關巨集的說明,將在之後的章節才會開始,現階段您只要知道若看到疑似函數的名稱後面接著驚嘆號!,就表示您正在使用Rust的巨集,而不是一般的函數。Rust程式碼中的字串定數(String Literals)一律使用一組雙引號""來包裝,有關字串的說明也會在之後的章節才會開始。一般來說,程式碼敘述的結尾會加上分號;,但在有些情況下並不需要加上分號,這個在之後的章節會再進行說明。

Cargo的使用方式

Cargo是Rust的程式碼專案相依性管理和建置工具,可以簡化很多事情。上一節我們寫的Hello World程式還沒有相依於其它的程式碼,所以我們可以簡單地使用rustc來編譯出Rust程式,但是如果我們的程式專案,需要用到其它專案的程式碼,用Cargo來管理和建置我們的程式專案會比較容易。

底下就讓我們先用Cargo來建立出一個Hello World專案試試看吧!

用Cargo建立Rust程式專案

使用Cargo建立Rust程式專案的方式非常簡單,指令如下:

cargo new <專案名稱>

預設會建立出可執行的應用程式專案,這種專案可以製作出給作業系統執行的程式執行檔。由於我們的Hello World本身就應該要是可以直接執行的程式,所以要使用這種類型的程式專案來開發。在習慣上,我們會加上--bin參數,確定建立出來的程式專案是可執行的應用程式專案。指令如下:

cargo new --bin <專案名稱>

如果要建立出可以被用來相依進其它專案中作為函式庫使用的函式庫程式專案,則是需要加上--lib參數。指令如下:

cargo new --lib <專案名稱>

所以,要使用Cargo建立出名為hello_world的可執行應用程式專案,可以輸入以下指令:

cargo new --bin hello_world

如此一來便會在當前工作目錄下產生出一個hello_world目錄,裡面已經有了Cargo.toml這個專案設定檔和存放Rust程式原始碼的src目錄,且這個src目錄中已經建立了main.rs這個Rust程式碼檔案。

用文字編輯器打開main.rs,更可以發現檔案中已經內建了我們在上一節寫好的Hello World程式碼!這是Cargo建立可執行應用程式專案會預先填寫的程式,如此一來新建出來的程式專案也可以直接被編譯執行了。稍候會告訴各位要怎麼用Cargo來編譯和執行專案,我們先來看看Cargo.toml這個設定檔吧!

TOML(Tom's Obvious, Minimal Language)是一種設定檔的格式,比YAML(YAML Ain't Markup Language)還要更簡潔優雅,Cargo選用了TOML作為其設定檔的格式。預設產生出來的Cargo.toml長成底下這個樣子:

[package]                                                                       
name = "hello_world"
version = "0.1.0"
edition = "2021"
 
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 
[dependencies]

第一行的[package]代表其和底下的敘述所組成的區域是用來撰寫專案的設定。最後一行的[dependencies]則是代表其和底下的敘述所組成的區域為這個專案需要使用到哪些「crate」(板條箱),「crate」是Rust對於套件的特別稱呼。將crate加進Cargo.toml檔案中的的[dependencies]區域,Cargo在建置專案的時候就會自動把相依的套件下載下來編譯。這個Hello World程式專案並不需要用到任何相依套件,因此我們不用動到這個區域的設定,讓它繼續維持什麼都沒有的狀態即可。

用Cargo建立出的程式專案來開發Rust程式,專案的檔案目錄結構需要依循Cargo訂定規則。Rust的程式碼,也就是那些*.rs檔案,通通都是放在src目錄中。至於其它跟Rust的程式碼無直接關係的檔案,例如Cargo.tomlREADMELICENSE等等的設定檔和文件,則是放在專案根目錄下,與Rust程式碼放置的位置區分開來。

用Cargo編譯專案

將終端機的工作目錄移動到Cargo專案根目錄,執行以下指令:

cargo build

rust-introduction

編譯成功後,Rust的程式執行檔會存放在專案根目錄的target/debug目錄中。但我們在開發階段通常不會直接從這個目錄中把執行檔案找出來執行。

用Cargo執行專案

執行以下指令:

cargo run

就可以看到程式專案的執行結果了!

rust-introduction

如果專案沒有事先使用cargo build進行編譯的話,直接使用cargo run也會先幫您進行編譯。

rust-introduction

用Cargo檢查專案有沒有問題

執行以下指令:

cargo check

這個指令會編譯專案,但不會產生出最終的目的檔(執行檔),可以快速驗證Rust的程式碼是否能通過編譯。

用Cargo發佈程式

在程式專案完結的時候,會需要進行最終的程式編譯輸出。與開發階段不同的是,作為產品輸出的程式應該要透過編譯器進行一些優化,並且移除掉開發階段時用來偵錯(debug)的功能和訊息,確保正式版本的程式能在最佳狀態下運作(高效能、小體積)。

和編譯專案的方式一樣,都是使用cargo build指令,只是需要加上--release參數。

cargo build --release

加上--release參數編譯出來的程式會放置在專案根目錄的target/release目錄中,提交給客戶或是部署到正式環境的程式就是在這邊領取啦!

用Cargo測試程式

開發程式時,除了要想辦法把功能完成之外,也要另外有個方式去驗證寫出來的程式是不是能正確執行。Cargo有提供測試專案的指令:

cargo test

這個指令會在後面的章節才會開始使用,現在還不需要去理解它。

清理Cargo程式專案

刪除Cargo在檢查、編譯或是測試程式專案時所產生出來的暫存檔案和執行檔案。

cargo clean

這個指令會把程式專案下的整個target目錄刪除。

rustfmt的使用方式

為了解決不同開發者有各自不同的程式碼風格的問題。像是有些人習慣用一個tab字元進行縮排;有些人則習慣用兩個或四個空格字元來進行縮排。有些人習慣if或for迴圈的大括號要先換行;有些人則習慣和關鍵字寫在同一行。Rust官方提供了rustfmt這個工具來進行官方建議的程式排版方式。

可以使用rustfmtcargo fmt指令來使用rustfmt工具了,指令格式如下:

rustfmt 檔案路徑1 [檔案路徑2 [檔案路徑3 [... 檔案路徑n]]]

例如:

rustfmt main.rs

如果要格式化整個Cargo專案的Rust程式碼。指令如下:

cargo fmt

Rust的IDE(Integrated Development Environment)

Rust提供了rust-analyzer來讓各種IDE能夠支援Rust,Visual Studio Code也有rust-analyzer插件能使其支援Rust程式的開發。

關於Visual Studio Code的介紹可以參考這篇文章:

rust-introduction

總結

在這一章中,我們設定好Rust的開發環境,學會了如何建立出Rust的程式碼專案,並且成功地編譯和執行Hello World程式,也瞭解了幾個在開發階段時,經常會用到的Cargo指令,例如:cargo buildcargo runcargo checkcargo fmtcargo test

在下一章節中,我們將會實際寫一個簡單的小程式,來學習Rust程式語言的基本概念和語法!

下一章,用Rust寫個猜數字程式吧!