整型

整数

整数是没有小数点的整数。整数有两种类型:有符号整数,无符号整数。ed Integers)。符号表示 +(加号)和 -(减号),因此带符号的整数可以为正数或负数(例如 +8,-8)。但是无符号整数只能是正数,因为它们没有符号。有符号整数是:i8i16i32i64i128isize。无符号整数是:u8u16u32u64u128usize

长度 有符号 无符号
8-bit i8 u8
16-bit i16 u16
32-bit i32 u32
64-bit i64 u64
128-bit i128 u128
arch isize usize

i 或 u 后面的数字表示该数字的位数,因此位数较多的数字可以更大。1 个字节包含 8 位,因此 i8 是 1 个字节,i64 是 8 个字节,依此类推。较大的数字类型可以容纳更大的数字。例如,一个 u8 最多可以容纳 255 个,但是一个 u16 最多可以容纳 65535 个。一个 u128 最多可以容纳 340282366920938463463374374431431768211455。isize 和 usize 类型依赖运行程序的计算机架构:64 位架构上它们是 64 位的,32 位架构上它们是 32 位的。因此,在 32 位计算机上进行 isize 和 usize 就像 i32 和 u32,而在 64 位计算机上进行 isize 和 usize 就像 i64 和 u64。

注意除 byte 以外的所有数字字面值允许使用类型后缀,例如 57u8,同时也允许使用 _ 做为分隔符以方便读数,例如 1_000。

数字字面值 例子
Decimal (十进制) 98_222
Hex (十六进制) 0xff
Octal (八进制) 0o77
Binary (二进制) 0b1111_0000
Byte (单字节字符)(仅限于u8) b'A'

类型转换

整数类型不同的原因很多。原因之一是计算机性能:较少的字节数处理速度更快。但这还有其他用途:Rust 中的字符称为 char。每个字符都有一个数字:字母 A 为数字 65,而字符(中文的“friend”)为数字 21451。数字列表称为“Unicode”。Unicode 对使用更多的字符使用较小的数字,例如 A 到 Z 或数字 0 到 9,或空格。

fn main() {
    let first_letter = 'A';
    let space = ' '; // A space inside ' ' is also a char
    let other_language_char = 'Ꮔ'; // Thanks to Unicode, other languages like Cherokee display just fine too
    let cat_face = '😺'; // Emojis are characters too
}

使用最多的字符得到的数字小于 256,可以放入 u8。这意味着 Rust 可以使用 as 安全地将 u8 转换为 char(将 u8 转换为 char 意味着“假装 u8 是一个 char”)。使用 as 进行转换非常有用,因为 Rust 非常严格。它总是需要知道类型,并且即使它们都是整数,也不会让您同时使用两种不同的类型。例如,这将不起作用:

fn main() { // main() is where Rust programs start to run. Code goes inside {} (curly brackets)

    let my_number = 100; // We didn't write a type of integer,
                         // so Rust chooses i32. Rust always
                         // chooses i32 for integers if you don't
                         // tell it to use a different type

    println!("{}", my_number as char); // ⚠️
}

error[E0604]: only `u8` can be cast as `char`, not `i32`
 --> src\main.rs:3:20
  |
3 |     println!("{}", my_number as char);
  |                    ^^^^^^^^^^^^^^^^^

幸运的是,我们可以使用 as 轻松解决此问题。我们不能将 i32 设为 char,但是可以将 i32 设为 u8。然后我们可以将 u8 设为 char。因此,在一行中,我们使用 as 将 my_number 设置为 u8,然后再次将其设置为 char。现在它将编译:

fn main() {
    let my_number = 100;
    println!("{}", my_number as u8 as char);
}

这是大小不同的另一个原因:usize 是 Rust 用于索引的大小(索引的意思是“哪个项目是第一个项目”,“哪个项目是第二个项目”等)。usize 是索引的最佳大小,因为:索引不能为负,因此它必须是一个带有 u 的数字,它应该很大,因为有时您需要索引很多东西,但是它不能是 u64,因为 32 位计算机不能使用它。因此,Rust 使用 usize,以便您的计算机可以获得最大数量的可读取索引。

Floats

浮点数是带小数点的数字。5.5 是浮点数,而 6 是整数。5.0 也是浮点数,甚至 5. 也是浮点数。Rust 也有两个原生的 浮点数(floating-point numbers)类型,它们是带小数点的数字。Rust 的浮点数类型是 f32 和 f64,分别占 32 位和 64 位。默认类型是 f64,因为在现代 CPU 中,它与 f32 速度几乎一样,不过精度更高。

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; // ⚠️
}

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 + // The compiler sees a new variable. It must be an f64 plus another f64. Now it expects an f64...
    let third_float = my_float + my_other_float;  // ⚠️ it found an f32. It can't add them.
}

当然,使用简单的数字很容易解决。您可以使用以下命令将 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 将选择可以加在一起的类型。

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; // Rust will choose f32,

    let third_float = my_float + my_other_float; // because it knows you need to add it to an f32
}

数值运算

Rust 中的所有数字类型都支持基本数学运算:加法、减法、乘法、除法和取余。下面的代码展示了如何在 let 语句中使用它们:

fn main() {
    // 加法
    let sum = 5 + 10;

    // 减法
    let difference = 95.5 - 4.3;

    // 乘法
    let product = 4 * 30;

    // 除法
    let quotient = 56.7 / 32.2;

    // 取余
    let remainder = 43 % 5;
}

这些语句中的每个表达式使用了一个数学运算符并计算出了一个值,然后绑定给一个变量。

最大值与最小值

如果要查看最小和最大的数字,可以使用 MIN 和 MAX。std 表示“标准库”,并具有 Rust 的所有主要功能等。稍后我们将学习标准库。但是与此同时,您可以记住,这是您获取类型的最小和最大数字的方式。

fn main() {
    println!("The smallest i8 is {} and the biggest i8 is {}.", std::i8::MIN, std::i8::MAX); // hint: printing std::i8::MIN means "print MIN inside of the i8 section in the standard library"
    println!("The smallest u8 is {} and the biggest u8 is {}.", std::u8::MIN, std::u8::MAX);
    println!("The smallest i16 is {} and the biggest i16 is {}.", std::i16::MIN, std::i16::MAX);
    println!("The smallest u16 is {} and the biggest u16 is {}.", std::u16::MIN, std::u16::MAX);
    println!("The smallest i32 is {} and the biggest i32 is {}.", std::i32::MIN, std::i32::MAX);
    println!("The smallest u32 is {} and the biggest u32 is {}.", std::u32::MIN, std::u32::MAX);
    println!("The smallest i64 is {} and the biggest i64 is {}.", std::i64::MIN, std::i64::MAX);
    println!("The smallest u64 is {} and the biggest u64 is {}.", std::u64::MIN, std::u64::MAX);
    println!("The smallest i128 is {} and the biggest i128 is {}.", std::i128::MIN, std::i128::MAX);
    println!("The smallest u128 is {} and the biggest u128 is {}.", std::u128::MIN, std::u128::MAX);
}

The smallest i8 is -128 and the biggest i8 is 127.
The smallest u8 is 0 and the biggest u8 is 255.
The smallest i16 is -32768 and the biggest i16 is 32767.
The smallest u16 is 0 and the biggest u16 is 65535.
The smallest i32 is -2147483648 and the biggest i32 is 2147483647.
The smallest u32 is 0 and the biggest u32 is 4294967295.
The smallest i64 is -9223372036854775808 and the biggest i64 is 9223372036854775807.
The smallest u64 is 0 and the biggest u64 is 18446744073709551615.
The smallest i128 is -170141183460469231731687303715884105728 and the biggest i128 is 170141183460469231731687303715884105727.
The smallest u128 is 0 and the biggest u128 is 340282366920938463463374607431768211455.
上一页