數值類型
Rust的數值類型包括整數和浮點數。有如下幾種類型:
長度 | 有符號 | 無符號 | 浮點數 |
---|---|---|---|
8-bit | i8 | u8 | |
16-bit | i16 | u16 | |
32-bit | i32(默認) | u32 | f32 |
64-bit | i64 | u64 | f64(默認) |
128-bit | i128 | u128 | |
word | isize | usize |
注: word表示一個機器字長,通常是一個指針的大小,大小和機器有關。64位機器的word是64-bit,32位機器的word是32-bit。
可以在數值字面量後加上類型來表示該類型的數值。例如:
fn main(){ let _a = 33i32; // 直接加類型後綴 let _b = 33_i32; // 使用_分隔數值和類型 let _c = 33_isize; let _d = 33_f32; }
如果數值較長,可以在任意位置處使用下劃線_
劃分數值,增加可讀性。
fn main(){ let _a = 33_333_33_i32; let _b = 3_333_333_i32; let _c = 3_333_333f32; }
當不明確指定變量的類型,也不明確指定數值字面量的類型後綴,Rust默認將整數當作i32類型,浮點數當作f64類型。
fn main(){ // 等價於 let _a: i32 = 33_i32; let _a = 33; // 等價於let _b: f64 = 64.123_f64; let _b = 64.123; }
每種數值類型都有所能存儲的最大數值和最小數值。當超出類型的有效範圍時,Rust將報錯(panic)。例如u8類型的範圍是0-255,它無法存儲256。
fn main() { let n: i32 = std::i32::MAX; // i32類型的最大值 println!("{}", n + 1); // 編譯錯誤,溢出 }
Rust允許使用0b 0o 0x
來表示二進制、八進制和十六進制的整數。
fn main(){ let a = 0b101_i32; // 二進制整數,i32類型 let b = 0o17; // 八進制整數,i32類型 let c = 0xac; // 十六進制整數,i32類型 println!("{}, {}, {}", a, b, c); // 5, 15, 172 }
數值類型之間默認不會隱式轉換,如果需要轉換數值類型,可手動使用as
進行轉換(as主要用於原始數據類型間的類型轉換)。例如3_i32 as u8
表示將i32類型的3轉換為u8類型。需注意,寬類型數值轉為窄類型數值時,如果溢出,則從高位截斷。
fn main(){ assert_eq!(10_i8 as u16, 10_u16); assert_eq!(2525_u16 as i16, 2525_i16); // 有符號類型->有符號類型 assert_eq!(-1_i16 as i32, -1_i32); // 有符號到無符號類型 assert_eq!(-1_i32 as u8, 255_u8); // 範圍溢出,截斷 assert_eq!(1000_i16 as u8, 232_u8); // 浮點數轉整數,小數部分被丟棄 assert_eq!(33.33_f32 as u8, 33_u8); }
Rust數值是一種類型的值,每種類型有自己的方法,因此數值也可以調用它們具有的方法。
fn main(){ // 需注意,下面的數值都加上了類型後綴。 // 這是因為在調用方法的時候,需要知道值的 // 所屬類型才能找到這種類型具有的方法 println!("{}", 3_u8.pow(2)); // 9 println!("{}", (-3_i32).abs()); // 3 // 4,計算45的二進制中有多少個1 println!("{}", 45i32.count_ones()); // 4 }
Rust將字節字面量存儲為u8類型,字節字面量的表示方式為b'X'
(b後面使用單引號包圍單個ASCII字符)。
例如A的ASCII碼為65,那麼b'A'
完全等價於65u8
。
fn main(){ let a = b'A'; // a的類型自動推導為u8 let b = a - 65; // b的類型也自動推導為u8 println!("{}, {}", a, b); // 65, 0 }
需注意,某些特殊ASCII字符需要使用反斜線轉義,例如b'\n', b'\'', b'\\'
。有些控制類的字符無法直接寫出來,此時可以使用十六進制法來表示,例如b'\x1b'
表示ESC按鍵的控制符。