型別推導
型別推導的意思是,如果你沒有告訴編譯器型別,但它可以自己判斷時它就會自己決定型別。編譯器總是必需知道變數的型別,但你不需要都告訴它。實際上,通常你不需要告訴它。例如,像 let my_number = 8
,my_number
將會是 i32
。這是因為如果你不告訴它,編譯器會給整數選擇 i32。但是如果你說 let my_number: u8 = 8
,它就會把 my_number
視為 u8
,因為你明確告訴它是 u8
。
通常編譯器都能猜到。但有時你需要告訴它,原因有兩個:
- 你正在做一些非常複雜的事情,而編譯器不知道你想要的型別。
- 你想要一個不同的型別 (例如,你想要一個
i128
,而不是i32
)。
這時可以指定一個型別,只要在變數名後新增一個冒號和型別。
fn main() { let small_number: u8 = 10; }
對數字來說,你可以在數字後面加上型別。你不需要空格──只需要在數字後面直接輸入。
fn main() { let small_number = 10u8; // 10u8 = 型別為 u8 的 10 }
如果你想讓數字容易閱讀,也可以加上 _
。
fn main() { let small_number = 10_u8; // 好讀 let big_number = 100_000_000_i32; // 用 _ 時更容易讀出是 100 百萬 }
_
不會改變數字。它只是為了讓你方便閱讀。而且你用多少個_
都沒有關係。
fn main() { let number = 0________u8; let number2 = 1___6______2____4______i32; println!("{}, {}", number, number2); }
這個程式會印出 0, 1624
.
浮點數
浮點數是帶有小數點的數字。5.5 是一個浮點數,6 是一個整數。5.0 也是一個浮點數,甚至 5. 也是一個浮點數。
fn main() { let my_float = 5.; // Rust 看到 . 時,知道它是 float }
但寫出型別時不叫 float
,叫 f32
和 f64
。這點和整數一樣:f
後面的數字顯示的是位元數。如果你不寫型別,Rust 會選擇 f64
。
當然,只有同樣型別的浮點數可以一起使用。所以你不能把 f32
和 f64
加起來。
fn main() { let my_float: f64 = 5.0; // 這是 f64 let my_other_float: f32 = 8.5; // 這是 f32 let third_float = my_float + my_other_float; // ⚠️ }
當你嘗試執行這個程式時,Rust 會說:
error[E0308]: mismatched types
--> src\main.rs:5:34
|
5 | let third_float = my_float + my_other_float;
| ^^^^^^^^^^^^^^ expected `f64`, found `f32`
當你用錯型別時,編譯器會寫 "expected (type), found (type)"。它是像這樣讀你的程式碼:
fn main() { let my_float: f64 = 5.0; // 編譯器見到 f64 let my_other_float: f32 = 8.5; // 編譯器見到 f32 是個不同型別 let third_float = my_float + // 你想把 my_float 加上什麼,所以它一定要是 f64 加上另一個 f64。現在它預期有另一個 f64… let third_float = my_float + my_other_float; // ⚠️ 不過它發現是個 f32。它沒辨法把它們加起來。 }
所以當你看到 "expected(type), found(type)" 時,你必須找到為什麼編譯器預期的是不同的型別。
當然,單純的數字很容易修正。你可以用 as
把 f32
轉型成 f64
:
fn main() { let my_float: f64 = 5.0; let my_other_float: f32 = 8.5; let third_float = my_float + my_other_float as f64; // my_other_float as f64 = 把 my_other_float 當 f64 來用 }
或者更簡單,去掉型別宣告。("宣告一個型別" = "告訴Rust使用該型別") Rust會選擇可以加在一起的型別。
fn main() { let my_float = 5.0; // Rust 會選 f64 let my_other_float = 8.5; // 這裡還是會選 f64 let third_float = my_float + my_other_float; }
Rust 編譯器很聰明,如果你需要 f32,就不會選擇 f64:
fn main() { let my_float: f32 = 5.0; let my_other_float = 8.5; // 通常 Rust 是選 f64, let third_float = my_float + my_other_float; // 但現在它知道你需要把它加上 f32。所以它也選了 f32 給 my_other_float }