整数类型
Rust 提供了丰富的整数类型,每种都明确指定位数和符号性。你可以根据需要选择合适的类型,既不会浪费内存,又能保证计算精度。
整数类型分为两大类:有符号(i 开头)和无符号(u 开头)。有符号可以表示正数、负数和零,无符号只能表示非负数。
整数类型的默认值都为0
1.1.1 固定宽度整数
有符号整数
每一个有符号的变体可以储存包含从 -2n-1 到 2n-1 - 1 在内的数字,这里 n 是变体使用的位数。
| 类型 | 长度 | 范围 |
|---|---|---|
i8 | 8-bit | [-27, 27-1] |
i16 | 16-bit | [-215, 215-1] |
i32 | 32-bit | [-231, 231-1] |
i64 | 64-bit | [-263, 263-1] |
i128 | 128-bit | [-2127, 2127-1] |
无符号整数
无符号的变体可以储存从 0 到 2n - 1 的数字
| 类型 | 长度 | 范围 |
|---|---|---|
u8 | 8-bit | [0 , 28-1] |
u16 | 16-bit | [0, 216-1] |
u32 | 32-bit | [0, 232-1] |
u64 | 64-bit | [0, 264-1] |
u128 | 128-bit | [0, 2128-1] |
1.1.2 架构相关整数
除了以上有符号和无符号的整数,还有两个根据架构相关的整数,isize和usize
isize 和 usize 的位数 n 取决于目标架构:
- 在 32 位系统(如 x86)上
n = 32 - 在 64 位系统(如 x64)上
n = 64
| 类型 | 长度 | 范围 |
|---|---|---|
isize | 32位系统:32-bit 64位系统:64-bit | 32位系统:-231 到 231-1 64位系统:-263 到 263-1 |
usize | 32位系统:32-bit 64位系统:64-bit | 32位系统:0 到 232-1 64位系统:0 到 264-1 |
架构相关的整数,可以在按照系统自适应整形大小。
如果你想知道某个类型到底占用多少字节,可以使用 std::mem::size_of:
use std::mem;
println!("i8: {} bytes", mem::size_of::<i8>()); // 1
println!("i32: {} bytes", mem::size_of::<i32>()); // 4
println!("i64: {} bytes", mem::size_of::<i64>()); // 8
println!("usize: {} bytes", mem::size_of::<usize>()); // 4 或 8size_of 返回的是字节数,不是位数。1 字节 = 8 位,所以 i32 占用 4 字节 = 32 位。
1.1.3 默认整型
上面说到rust具有类型推导,当声明一个整数时,默认为i32
当直接写整数字面量时,默认使用 i32:
let x = 42; // 推断为 i32这是因为 i32 在大多数场景下是性能和空间的最佳平衡点,即使在 64 位系统上也是如此。
1.1.4 整数溢出
Rust 的程序构建时,分为两种模式,debug调试构建 和 release发布构建。
在 debug 模式下,会有更多的调试信息输出,一般用于开发环境。而 release 下会对代码进行更大幅度的优化,运行效率更高,一般用语正式发布环境。
当一个整数发生溢出的时候,在两个环境下效果也不同。
在 debug 模式下,如果整数溢出,此时会直接报错,在 Rust 中称为 panic。这会导致整个程序直接终止。
但是在 release 下,如果溢出会发生环绕。
比如:
let mut x: u8 = 255;
x += 1;
println!("x: {}", x);这段代码在 debug 模式下直接报错退出,但是在 release 下输出 x: 0。因为 255 已经是 u8 的最大值了,当再加一个数,就会重新变回最小的值,这个过程称为环绕。
其实环绕大部分情况下是一个非常危险的操作,在开发的时候,Rust倾向于直接把这个行为作为一个错误报告给开发者,让开发者可以修改代码逻辑,或者更改更大的类型。
但是在实际发布环境,程序崩溃往往会给用户带来不好的体验,那么Rust就不再把它当做一个错误处理了。
