變數與資料型別
Rust 是靜態型別語言:每個值在編譯時就有確定的型別。本頁介紹如何宣告變數、Rust 預設「不可變」的設計原因,以及最常用的內建型別。
變數與可變性
用 let 宣告變數。變數預設不可變(immutable),要修改就必須加上 mut:
fn main() {
let x = 5;
// x = 6; // 編譯錯誤:不能對不可變變數重新賦值
let mut y = 5;
y = 6; // 加了 mut 才可以修改
println!("x = {x}, y = {y}");
}
預設不可變的好處是:讀程式時能確定哪些值不會變,減少意外的副作用,也讓編譯器更容易保證並行安全。
常數
const 是編譯時就決定的值,必須標註型別,命名慣例為全大寫:
數字中的底線 _ 只是方便閱讀的分隔符號。
遮蔽(shadowing)
用同一個名字再次 let,會建立一個新的變數遮蔽舊的。這和 mut 不同,遮蔽時甚至可以改變型別:
fn main() {
let spaces = " "; // &str
let spaces = spaces.len(); // usize,型別已經改變
println!("{spaces}");
}
純量型別
純量(scalar)型別代表單一的值,共有四種。
| 型別 | 說明 | 範例 |
|---|---|---|
| 整數 | 有號 i8~i128、isize;無號 u8~u128、usize |
let n: i32 = -42; |
| 浮點數 | f32、f64(預設) |
let pi = 3.14159; |
| 布林 | bool,只有 true/false |
let ok = true; |
| 字元 | char,代表一個 Unicode 純量值(4 位元組) |
let c = '中'; |
整數若沒有標註型別,預設是 i32。usize 的大小依平台而定,常用於索引與長度。
fn main() {
let a: i32 = 10;
let b = 3.5_f64;
let flag = true;
let heart = '🦀';
println!("{a} {b} {flag} {heart}");
// 不同數值型別不能直接運算,需要明確轉換
let total = a as f64 + b;
println!("{total}");
}
整數溢位
以 debug 模式編譯時,整數溢位會 panic(程式中止);release 模式則會回繞(wrap around)。如果需要明確的行為,可使用 checked_add、wrapping_add、saturating_add 等方法。
複合型別
複合(compound)型別能把多個值組合在一起。
Tuple
長度固定,各元素型別可以不同:
fn main() {
let person = ("小明", 30, 175.5);
// 解構
let (name, age, height) = person;
println!("{name} {age} {height}");
// 用索引存取
println!("{}", person.0);
}
陣列(array)
長度固定,元素型別必須相同,資料放在堆疊上:
fn main() {
let nums = [1, 2, 3, 4, 5];
let zeros = [0; 3]; // [0, 0, 0]
println!("{} {}", nums[0], zeros.len());
}
存取超出範圍的索引,程式會在執行時 panic,而不是讀到錯誤的記憶體。想要可以成長的序列,請用 Vec<T>,見 字串與集合。
推薦影音
純量資料型別
簡述:微軟《Beginner's Series to Rust》第 9 集,介紹整數、浮點數、布林與字元,對應本頁「純量型別」一節。
複合資料型別
簡述:同系列第 11 集,介紹 tuple 與陣列,對應本頁「複合型別」一節。
下一頁:控制流程。