Rust 學習筆記:一般程式概念(上)
September 30, 2023 · Chinese
前言
本系列文書寫我個人初探 Rust 的學習筆記,章節劃分主要基於著名的 The Book,The Rust Programming Language,程式碼部分通常是個人閱讀消化後以方便說明的方式撰寫,完整學習建議直接參見該書。
The Rust Programming Language
該書也有中文翻譯版,不過個人閱讀以英文原版為主以鞏固對 terminology 的一致認識,我認為對未來閱讀以及查找資料會較為順暢。
不論語言該書都是相當優秀的學習資源,選擇適合你的語言開始學習 Rust 吧。
Appendix F: Translations of the Book
變數 (Variables)
在 Rust 中變數以 let
進行宣告,如果學習過 Javascript 的人應該會感到非常熟悉。
let x = "Hello world";
要注意的是 Rust 中變數預設是不可變的 (immutable),因此如果執行下列程式會出現錯誤。
let x = "Hello world"; x = "Hi world"; // ERROR: cannot assign twice to immutable variable `x`
若要讓變數成為可變的變數,可以利用 mut
keyword。
let mut x = "Hello world"; x = "Hi world"; // OK
Const
在 Rust 中常數以 const
宣告。與 let
不同的是 const
無法使用 mut
讓其可變,const
應該永遠是不可變的。同時 const
要在宣告時給予型別,不像 let
會進行推論。
常數的 naming convention 為全大寫的 snake case。
const FIRST_CONST: i32 = 0; const mut SECOND_CONST: i32 = 1; // ERROR: const globals cannot be mutable
Shadowing
可以利用宣告相同的變數名稱在當前 scope 中進行 shadowing。
let a = 0; let a = 6; println!("{}", a); // 6 let a = "Hello"; println!("{}", a); // Hello
與 mut 的差別
利用 mut 宣告可變變數後,變數的型別仍然是不可變的,但我們可以使用 shadowing 將相同變數名稱宣告為不同型別的變數。
型別 Types
Rust 是靜態型別語言,釐清型別至關重要。
Scalar Types
Scalar Types 代表單一值,Rust 中有四種主要的 Scalar Types。
- Integer 整數
- Float 浮點數
- Boolean 布林值
- Character 字元
各種類型的詳細可見 Data Types,學過計概的人應該都不陌生我想就不再贅述。
Rust 預設的整數型別為 i32
即有號 32 位元整數,浮點數則為 f64
即雙精度浮點數。
Compound Types
Compound Types 是一組複數值,Rust 有兩種原始 compound type,tuple (元組) 與 array (陣列)。
Tuple 元組
tuple 可以含有不同型別,其具有固定長度。可以利用 destructure 解構讀取其值。
let tup = ("hello", "world", 5); let (x, y, z) = tup; println!("{}", x); // hello
也可以用 dot notation 讀取。
println!("{}", tup.1); // world
Array 陣列
陣列中元素的型別必須是一樣的,以中括號表示。
let arr = [10, 20, 30, 40, 50];
另一種宣告法,可以利用這種方式建立陣列並填充相同元素的陣列,以下則為建立一個內含 10 個 10 的陣列。
let arr = [10; 10];
和多數程式語言一樣,利用 index assign 和 read 陣列元素。若要 assign 陣列元素需要宣告 mutable array。
let mut arr = [0; 10]; println!("{}", arr[5]); // 0 arr[5] = 10; println!("{}", arr[5]); // 10
函式 Functions
在 Rust 中我們用 fn
建立函式。
fn main() { say_hello(); // Hello } fn say_hello() { println!("Hello"); }
我們可以宣告函式參數,這邊給 say_hello
一個參數,類型為 &str
,這是字串的 slice 以 reference 的形式傳入,在後面的章節會有詳細學習。
fn main() { say_hello("Josh"); // Hello Josh } fn say_hello(name: &str) { println!("Hello {}", name); }
returning value
使用單箭頭號 ->
宣告回傳值的型別,我們可以利用 return
將值回傳。
fn main() { let result = sum(5, 6); println!("{}", result); // 11 } fn sum(a: i32, b: i32) -> i32 { let sum = a + b; return sum; }
Rust 能使用最後一行的 expression 進行回傳而不使用 return
,因此上述的程式可以簡化為如下:
fn main() { let result = sum(5, 6); println!("{}", result); // 11 } fn sum(a: i32, b: i32) -> i32 { a + b }
注意上面的 a + b
不能加上分號,否則會變成沒有任何回傳值的 statement,函式將會報錯回傳值與宣告不匹配。
補充: Statements and Expressions
寫在最後
本來想一篇寫完這個章節,不過後面還有不少篇幅,流程控制我就留到下篇再寫囉。