Rust 數(shù)據(jù)類型詳解
一、標量類型(Scalar Types)
標量類型代表一個單獨的值。Rust 中有四大基本標量類型:整數(shù)(integer)、浮點數(shù)(floating-point number)、布爾(boolean)和字符(character)。這幾種類型在大多數(shù)編程語言中都很常見。
1. 整數(shù)類型(Integer Types)
整數(shù)(integer)是沒有小數(shù)部分的數(shù)字。在之前的猜數(shù)字游戲教程里,我們用到了 u32。這個類型聲明表示該值是一個無符號(unsigned)32 位整數(shù)(如果是有符號類型,會以 i 開頭,例如 i32)。
下表展示了 Rust 中所有內(nèi)置的整數(shù)類型,每個類型要么是有符號(signed),要么是無符號(unsigned),并且有明確的位數(shù)大小。
| 長度 | 有符號 | 無符號 |
|---|---|---|
| 8-bit | i8 | u8 |
| 16-bit | i16 | u16 |
| 32-bit | i32 | u32 |
| 64-bit | i64 | u64 |
| 128-bit | i128 | u128 |
| arch | isize | usize |
- 有符號(signed)表示數(shù)值可能為正也可能為負,所以存儲時需要符號位;
- 無符號(unsigned)則只表示非負數(shù)(0 或正數(shù)),不需要符號位。
對于有符號整數(shù),如果類型是 i8,它可以存儲從 -128 到 127 的數(shù)值;若是 i16,則范圍會相應(yīng)擴大,以此類推。無符號類型則從 0 起算。例如 u8 能表示 0 到 255。
isize 和 usize 根據(jù)系統(tǒng)架構(gòu)的不同而變化:在 64 位架構(gòu)上是 64 位,在 32 位架構(gòu)上是 32 位。這些類型常用于根據(jù)系統(tǒng)架構(gòu)進行索引或內(nèi)存大小計算等場景。
1.1 整數(shù)字面量
在 Rust 中可以使用多種形式來表達整數(shù)字面量(literal),如下表所示:
| 數(shù)字字面量形式 | 示例 |
|---|---|
| 十進制 | 98_222 |
| 十六進制 | 0xff |
| 八進制 | 0o77 |
| 二進制 | 0b1111_0000 |
字節(jié)(僅限 u8) | b'A' |
注意:
- 可以在數(shù)字中使用下劃線
_作為分隔符來提高可讀性,例如1_000與1000等價。 - 如果需要指定類型,可以在數(shù)字后面加上類型后綴,比如
57u8。
通常如果不確定該用什么整數(shù)類型,Rust 默認使用 i32。若需要根據(jù)系統(tǒng)架構(gòu)進行索引等場景時,才考慮使用 isize 或 usize。
1.2 整數(shù)溢出(Integer Overflow)
假設(shè)我們有一個 u8 類型的變量,它能表示的數(shù)值范圍是 [0, 255]。如果嘗試將其賦值為 256,就會發(fā)生整數(shù)溢出(integer overflow),導致以下兩種行為之一:
- 調(diào)試(debug)模式編譯:Rust 會執(zhí)行溢出檢查,一旦發(fā)現(xiàn)溢出,就會在運行時 panic(程序崩潰并退出)。
- 發(fā)布(release)模式編譯:Rust 不做溢出檢查,而是進行二補碼環(huán)繞(two’s complement wrapping)。換言之,超出最大可表示值時會“環(huán)繞”回最小值。例如,對于
u8類型,256 會變成 0,257 會變成 1,等等。不會出現(xiàn) panic,但是結(jié)果往往與期望不符。
在實際開發(fā)中,不應(yīng)依賴整數(shù)溢出的環(huán)繞行為,這被認為是錯誤的做法。若需要顯式處理溢出,可以使用標準庫里為整數(shù)提供的以下方法族:
wrapping_*:如wrapping_add,始終進行環(huán)繞運算;checked_*:如checked_add,若溢出則返回None;overflowing_*:如overflowing_add,返回一個元組(結(jié)果, bool),其中bool指示是否發(fā)生溢出;saturating_*:如saturating_add,在溢出時結(jié)果會自動“飽和”到對應(yīng)類型的最小或最大值。
2. 浮點數(shù)類型(Floating-Point Types)
Rust 提供了兩種原生的浮點數(shù)類型:f32(32 位)和 f64(64 位)。默認使用 f64,因為在現(xiàn)代 CPU 上,f64 與 f32 速度幾乎相當,但精度更高。所有浮點類型都是有符號數(shù)。
fn main() {
let x = 2.0; // f64
let y: f32 = 3.0; // f32
println!("x = {}, y = {}", x, y);
}Rust 的浮點數(shù)遵循 IEEE-754 標準。
3. 數(shù)值運算(Numeric Operations)
Rust 支持常見的數(shù)值運算:加法、減法、乘法、除法和取余。需要注意的是,整數(shù)除法會向零方向取整(截斷小數(shù)部分)。示例:
fn main() {
// 加法
let sum = 5 + 10;
// 減法
let difference = 95.5 - 4.3;
// 乘法
let product = 4 * 30;
// 除法
let quotient = 56.7 / 32.2;
// 取余
let remainder = 43 % 5;
println!("sum = {}", sum);
println!("difference = {}", difference);
println!("product = {}", product);
println!("quotient = {}", quotient);
println!("remainder = {}", remainder);
}如果需要查看 Rust 提供的所有運算符,可以參考 附錄 B。
4. 布爾類型(Boolean Type)
布爾類型(bool)只有兩個可能的值:true 和 false。它所占的大小是 1 個字節(jié)。例如:
fn main() {
let t = true;
let f: bool = false;
println!("t = {}, f = {}", t, f);
}布爾常常用于條件判斷(如 if 表達式),后面會在“控制流”一節(jié)詳述。
5. 字符類型(Character Type)
Rust 的 char 類型是最基礎(chǔ)的字母類型,用單引號包裹,支持 Unicode Scalar Value。這意味著它可以表示除 ASCII 之外更多的字符,比如帶重音的拉丁字符、中文、日文、韓文、emoji、零寬空格等。例如:
fn main() {
let c = 'z';
let z = '?';
let heart_eyed_cat = '??';
println!("{}, {}, {}", c, z, heart_eyed_cat);
}Rust 的 char 類型占 4 個字節(jié),對應(yīng) Unicode Scalar Value 范圍:U+0000 ~ U+D7FF 和 U+E000 ~ U+10FFFF。需要注意的是,Unicode 的“字符”概念可能與人們直覺中的“字符”不完全一致。詳情可參考第 8 章關(guān)于字符串的討論。
二、復合類型(Compound Types)
復合類型可以將多個值組合成一個類型。Rust 提供了兩種原生的復合類型:元組(tuple)和數(shù)組(array)。
1. 元組類型(Tuple Type)
元組(tuple)可以將多個類型各異的值組合到一個復合類型中,長度固定,不可增長或縮短。使用小括號 () 包含并用逗號分隔不同的值。例如:
fn main() {
let tup: (i32, f64, u8) = (500, 6.4, 1);
println!("tup = {:?}", tup);
}1.1 解構(gòu)(Destructuring)元組
要獲取元組中的單獨值,可以使用模式匹配(pattern matching)進行解構(gòu):
fn main() {
let tup = (500, 6.4, 1);
let (x, y, z) = tup;
println!("y = {}", y);
}執(zhí)行后,y 的值就是 6.4。這里 tup 被“拆解”成了 x, y, z 三個變量的過程,稱為解構(gòu)。
1.2 使用索引訪問元組
也可以直接用點號加索引來訪問元組的指定元素:
fn main() {
let x: (i32, f64, u8) = (500, 6.4, 1);
let five_hundred = x.0;
let six_point_four = x.1;
let one = x.2;
println!("{}, {}, {}", five_hundred, six_point_four, one);
}需要注意,索引從 0 開始。
1.3 單元類型(Unit Type)
如果元組不包含任何元素,則被稱為單元元組(unit)。它寫作 (),表示一種空值或空的返回類型。若一個表達式?jīng)]有返回任何其他值,默認會返回單元元組。
2. 數(shù)組類型(Array Type)
數(shù)組(array)也是一種把多個值組合在一起的方式,但它與元組有兩個主要區(qū)別:
- 數(shù)組中所有元素類型相同;
- 數(shù)組長度固定,一旦聲明,長度就無法改變。
例如:
fn main() {
let a = [1, 2, 3, 4, 5];
println!("{:?}", a);
}數(shù)組通常存儲在棧上(stack)而不是堆上(heap),這在 第 4 章 會詳細解釋。若需要一個可伸縮的序列,則使用標準庫提供的 向量(vector,Vec<T>)。如果你需要一個長度固定的序列,數(shù)組就非常合適。比如月份名稱:
let months = [
"January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December"
];2.1 數(shù)組的類型注解
聲明數(shù)組類型時,需要在方括號里寫元素類型、分號、元素個數(shù):
let a: [i32; 5] = [1, 2, 3, 4, 5];
這里 i32 是每個元素的類型,5 表示數(shù)組長度。
2.2 初始化為相同元素
如果想讓數(shù)組的所有元素都相同,可以使用如下語法:
let a = [3; 5]; // 等價于 let a = [3, 3, 3, 3, 3];
2.3 訪問數(shù)組元素
可以使用索引來訪問數(shù)組元素:
fn main() {
let a = [1, 2, 3, 4, 5];
let first = a[0];
let second = a[1];
println!("first = {}, second = {}", first, second);
}2.4 越界訪問與運行時錯誤
如果索引超出了數(shù)組的長度,Rust 會在運行時檢查到錯誤并 panic:
fn main() {
let a = [1, 2, 3, 4, 5];
println!("請輸入一個數(shù)組索引。");
let mut index = String::new();
std::io::stdin()
.read_line(&mut index)
.expect("讀取失敗");
let index: usize = index
.trim()
.parse()
.expect("輸入的索引不是數(shù)字");
let element = a[index];
println!("你選擇的元素是:{}", element);
}如果你輸入了超出 [0..4] 范圍的索引,比如 10,就會引發(fā) panic,顯示類似:
thread 'main' panicked at 'index out of bounds: the len is 5 but the index is 10', src/main.rs:19:19
程序因此退出并不會執(zhí)行后續(xù)的 println!。這是 Rust 保證內(nèi)存安全的體現(xiàn):許多低級語言在越界索引時可能會訪問非法內(nèi)存地址,引發(fā)不可預(yù)料的后果,而 Rust 直接在運行時檢測并退出以保證安全。
小結(jié)
在本篇文章中,我們介紹了 Rust 最常用的兩種數(shù)據(jù)類型子集:標量類型和復合類型。標量類型包括整數(shù)、浮點數(shù)、布爾和字符,它們各自有不同的表示和范圍;復合類型包括元組和數(shù)組,可以用于將多個值組合到一個類型中,并且在長度是否可變和類型一致性方面有所區(qū)別。
- 標量類型:
- 整數(shù):如
i32,u32,i8,u8等,不同字長和有符號/無符號選擇; - 浮點數(shù):
f32和f64,默認使用f64; - 布爾:
bool,僅有true和false; - 字符:
char,占 4 字節(jié),可表示 Unicode Scalar Value。
- 整數(shù):如
- 復合類型:
- 元組:可含多種類型,長度固定;可用解構(gòu)或索引方式訪問;
- 數(shù)組:同類型元素的集合,長度固定,存儲于棧上。
對于新手而言,遇到無法自動推斷類型的情形時,需要加上類型注解,尤其是在使用 parse 或其他需要指明具體數(shù)值類型的場景下。隨著實踐的深入,Rust 提供的多種安全檢查機制(如整數(shù)溢出檢查、數(shù)組越界檢查等)會給予你更多信心和安全感,同時也需要你熟悉這些機制以寫出高效且安全的代碼。
在后續(xù)章節(jié)中,我們將會不斷深入 Rust 的特性,包括所有權(quán)、引用與切片、集合類型(向量、字符串、哈希映射)以及錯誤處理等,希望你能繼續(xù)保持對 Rust 的探索與學習。
參考與致謝
- The Rust Programming Language - By Steve Klabnik and Carol Nichols, CC BY 4.0
- 本文部分內(nèi)容基于其翻譯和改寫,如需了解更多細節(jié),請閱讀官方文檔。
到此這篇關(guān)于Rust 數(shù)據(jù)類型詳解的文章就介紹到這了,更多相關(guān)Rust 數(shù)據(jù)類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Rust 中單線程 Web 服務(wù)器的實現(xiàn)
本文用Rust構(gòu)建單線程Web服務(wù)器,通過HTTP/TCP處理請求,返回hello.html或404.html,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2025-06-06
rust中間件actix_web在項目中的使用實戰(zhàn)
這篇文章主要介紹了rust中間件在項目中的使用實戰(zhàn),包括自定義中間件,日志中間件,Default?headers,用戶會話,錯誤處理的用法實例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2024-01-01

