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作業系統)

執行以下指令:

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

rust-introduction

接著用vim或是其他文字編輯器開啟家目錄中的「.bashrc」檔案:

vim ~/.bashrc

在檔案中加入這行:

直接套用新的環境設定:

source ~/.bashrc

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

安裝rustup(Windows作業系統)

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

https://rustup.rs/

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

rust-introduction

可以利用以下連結下載到「Visual C++ Build Tools」的安裝程式──「Build Tools for Visual Studio 2017」。

https://www.visualstudio.com/downloads/

執行「Build Tools for Visual Studio 2017」會需要.NET Framework 4.6以上的版本。如果Windows沒有安裝的話就會出現以下錯誤訊息:

rust-introduction

.NET Framework 4.7.1離線安裝檔的下載網址:

https://www.microsoft.com/zh-TW/download/details.aspx?id=56116

確定.NET Framework 4.6以上的版本安裝好之後,就可以執行「Build Tools for Visual Studio 2017」的安裝程式,來安裝「Visual C++ Build Tools」(Windows SDK也必須安裝)。

rust-introduction

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

rust-introduction

選擇「Proceed with installation」就能開始安裝。將Rust和Rust包含的相關工具安裝好之後,還需要將「%USERPROFILE%\.cargo\bin」路徑加至「PATH」環境變數。

rust-introduction

使用rustup

切換Rust版本:

rustup default <toolchain>

例如切換成nightly:

rustup default nightly

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

rustup default stable

例如切換成指定版本:

rustup default 1.24.0

升級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 ~/rust_projects/hello_world && cd ~/rust_projects/hello_world

建立Rust原始碼檔案

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

touch main.rs

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

存檔之後,就可以使用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程式究竟是在做什麼。先看一下程式碼的第一行和第三行:

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

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

在「main」函數中,我們加入了這行敘述「println!("Hello, world!");」。這行程式的目的就是將「Hello, world!」文字印出在螢幕上,並且進行換行的動作。如果您有學過其他語言,或許對「print」、「log」等等的函數已經足夠熟悉,然而,在這個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]」代表其和底下的敘述所組成的區域是用來撰寫專案的設定。最後一行的「[dependencies]」則是代表其和底下的敘述所組成的區域為這個專案需要使用到哪些「crate」(板條箱),「crate」是Rust對於套件的特別稱呼。將crate加進「Cargo.toml」檔案中的的「[dependencies]」區域,Cargo在建置專案的時候就會自動把相依的套件下載下來編譯。這個Hello World程式專案並不需要用到任何相依套件,因此我們不用動到這個區域的設定,讓它繼續維持什麼都沒有的狀態即可。

用Cargo建立出的程式專案來開發Rust程式,專案的檔案目錄結構需要依循Cargo訂定規則。Rust的程式碼,也就是那些「*.rs」檔案,通通都是放在「src」目錄中。至於其它跟Rust的程式碼無直接關係的檔案,例如「Cargo.toml」、「README」、「LICENSE」等等的設定檔和文件,則是放在專案根目錄下,與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」這個工具來進行官方建議的程式排版方式。使用前需先透過rustup來安裝「rustfmt-preview」,指令如下:

rustup component add rustfmt-preview

接著就可以使用rustfmt指令了,指令格式如下:

rustfmt <檔案名稱或路徑>

例如:

rustfmt main.rs

甚至也可以利用Cargo來格式化整個專案的程式碼。指令如下:

cargo fmt

Rust的IDE(Integrated Development Environment)

Rust提供了Rust Language Server來讓各種IDE能夠支援Rust,不過現階段的選擇不是很多,筆者都用IntelliJ IDEA Ultimate外加Rust的插件。

https://intellij-rust.github.io/

rust-introduction

總結

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

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