但是又不需要囉嗦的每個都寫說是什麼型別,因為 Rust 有 Type inference 會自動推論
Rust 的資料型別有兩大類:純量 (Scalar)、複合型 (Compound)
純量有整數 (Integer)、浮點數 (Floating-Point)、Boolean、字元 (Character)
複合型有 tuple、陣列 (Array)
萬物形色多樣,卻又同由固定的基本元素構成,是型態構成型態?
Photo by Jeremy Thomas on Unsplash |
整數
又細分成不同長度 (bit size)一般來說系統程式語言都會分,因為較接近硬體所以應該更詳細定義使用的大小
當然能用更小的表示當然就用小的,較省空間
其中比較特別的是"系統架構"那列,它會依照執行程式的電腦的系統架構 (32 or 64) 去改變
長度 | Signed | Unsigned |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
系統架構 | isize | usize |
其他特性:
後綴型別修飾 e.g. 57u8
視覺化的分隔 e.g. 1_000
一般來說,沒有寫就是預設使用 i32 (官方說 i32 執行最快)
上 code:(就不寫 fn main(){} 喔,這樣比較乾淨)
e.g. 1.
Rust 允許先宣告之後再定義給值 (宣告 vs 定義)
這裡就不需要 mut 喔,如果寫了編譯器也會發警告建議不要加 mut
let x; // 沒有宣告 x 的型別 x = 5; // 5 沒加後綴修飾就預設為 i32,所以編譯時就能確定 x 是 i32
e.g. 2.
宣告時加上型別,變數後方用":"加上型別
不加 into() 會 error,因為應該使用 u16 (和 x 相同)
所以 into() 是 Rust 針對小型別轉大型別而提供的函數
作法:unsigned 是直接補 0(zero-extend),signed 使用 sign-extend
使用 as 轉型可能會 overflow 但不會有 overflowing_literals 的警告
例如 256u32 as u8 就不是 256 而是 0,因為 u8 只有用 8-bit 存數字
let mut x: u16; // 宣告 x 的型別是 u16 x = 5u8.into(); // 小轉大型別:使用 into() 轉型 x = 5u32 as u16; // 大轉小型別:使用 as 來轉型
e.g. 3.
let x: u16 = 5; // 宣告 x 的型別是 u16 並定義 x 的數值
e.g. 4.
比較一下想想為什麼吧 OuO
fn main() { let x = 256; let y = x + 8; println!("x: {}, y: {}",x, y) // x: 256, y: 264 }
fn main() { let x = 256; let y = x + 8u8; println!("x: {}, y: {}",x, y) // x: 0, y: 8 }
結果光是整數就這麼長篇幅 QuQ,再來是....
浮點數
根據IEEE-754標準關鍵字:f32 (單精度)、f64 (倍精度)
預設為 f64,因為速度差不多
基本上用法與整數相同
let x = 2.0; // f64 let y: f32 = 3.0; // f32
Boolean
關鍵字:bool值有兩種:true、false
主要使用在流程控制 (condition、loop) 中
let t = true; let f: bool = false; // 有型別標示
字元
關鍵字:char不是用 ASCII 而是 Unicode,所以就需要 4 bytes 來存
說到 unicode 就代表所有符號都可以存,甚至包括中文、emoji
let c: char = 'z'; let z = 'ℤ'; let heart_eyed_cat = '😻';
tuple
這在 python 也有,也很像 Lisp 中的 values + multiple-value-bind就是可以把不同型別用 () 包成一個型別
最方便的就是可以讓函式有多個回傳值 (事實上還是只有一個)
fn main() { let (i, c) = get_int_and_char(); println!("{} {}", i, c); // 5 c let x = get_int_and_char(); println!("{} {}", x.0, x.1); // 5 c } fn get_int_and_char() -> (i32, char) { (5i32, 'c') // 不加 ";" 會變成表達式(Expression),會回傳本身,之後會再提 }
陣列
這超常見的啊,應該不需要多做解釋與 tuple 不同的就是內容必須要同型別
let a: [i32; 3] = [1, 2, 3]; // ": [i32; 3]" 可省略 println!("{}", a[2]); // 3
複合型別超出範圍的存取
let x = (1, 'd'); println!("{}", x.2); // --> 編譯時期:error[E0612] let a = [1, 2]; println!("{}", a[2]); // --> 執行時期:panicked (編譯會過)<107.06.02更新>
那為什麼呢?
原因是因為 tuple 存取只會出現數字 (.0, .1, .2),但是 array 可以出現變數 ([x], [y], [z])
而變數的值較難在編譯時期就決定,因此就會在執行時期中斷,同樣的 vector 也是如此
-
Make ‘index out of bounds’ a compile-time error
感覺還是不夠快啊 QuQ
謀斗骸雅庫~
下一篇 函式 (Function)
沒有留言:
張貼留言