类型推导

类型推导的意思是,如果你不告诉编译器类型,但它可以自己决定,它就会决定。编译器总是需要知道变量的类型,但你并不总是需要告诉它。实际上,通常你不需要告诉它。例如,对于let my_number = 8my_number将是一个i32。这是因为如果你不告诉它,编译器会选择i32作为整数。但是如果你说let my_number: u8 = 8,它就会把my_number变成u8,因为你告诉它u8

通常编译器都能猜到。但有时你需要告诉它,原因有两个。

  1. 你正在做一些非常复杂的事情,而编译器不知道你想要的类型。
  2. 你想要一个不同的类型(例如,你想要一个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,叫f32f64。这和整数一样: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)"时,你必须找到为什么编译器预期的是不同的类型。

当然,用简单的数字很容易解决。你可以用asf32转成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
}