类型推导
类型推导的意思是,如果你不告诉编译器类型,但它可以自己决定,它就会决定。编译器总是需要知道变量的类型,但你并不总是需要告诉它。实际上,通常你不需要告诉它。例如,对于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 = 10 of type u8 }
如果你想让数字便于阅读,也可以加上_
。
fn main() { let small_number = 10_u8; // This is easier to read let big_number = 100_000_000_i32; // 100 million is easy to read with _ }
_
不会改变数字。它只是为了让你方便阅读。而且你用多少个_
都没有关系。
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 sees . and knows that it is a float }
但类型不叫float
,叫f32
和f64
。这和整数一样:f
后面的数字显示的是位数。如果你不写类型,Rust会选择f64
。
当然,只有同一类型的浮点数可以一起使用。所以你不能把f32
加到f64
上。
fn main() { let my_float: f64 = 5.0; // This is an f64 let my_other_float: f32 = 8.5; // This is an 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; // The compiler sees an f64 let my_other_float: f32 = 8.5; // The compiler sees an f32. It is a different type. let third_float = my_float + // You want to add my_float to something, so it must be an f64 plus another f64. Now it expects an f64... let third_float = my_float + my_other_float; // ⚠️ but it found an f32. It can't add them. }
所以,当你看到 "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 = use my_other_float like an f64 }
或者更简单,去掉类型声明。("声明一个类型"="告诉Rust使用该类型")Rust会选择可以加在一起的类型。
fn main() { let my_float = 5.0; // Rust will choose f64 let my_other_float = 8.5; // Here again it will choose 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; // Usually Rust would choose f64, let third_float = my_float + my_other_float; // but now it knows that you need to add it to an f32. So it chooses f32 for my_other_float too }