Rust中的每个值都有一个特定类型,这是告知Rust数据是哪种类型,便于Rust怎样处理数据。我将看到两种数据型分类:标量和组合
记住Rust是一个静态类型语言,这意味着它必须在编译时知道所有变量的类型。编译器通常推断出我们想使用什么类型的值并且怎样使用它。如果有一些可能的类型,比如将String转换成数值类型,如在第二章猜数字的游戏中,我们必须添加类型声明,像下面这样:(这里的意思是,在声明一个变直接赋值时,变量可以不指定类型,但在转型时必须指定)
let guess: u32 = "42".parse().expect("Not a number!");
上面如果不加:u32类型说明,Rust会显示以下错误,这说明编译器想从我们这里得到更多类型信息:
$ cargo build
Compiling no_type_annotations v0.1.0 (file:///projects/no_type_annotations)
error[E0282]: type annotations needed
--> src/main.rs:2:9
|
2 | let guess = "42".parse().expect("Not a number!");
| ^^^^^ consider giving `guess` a type
For more information about this error, try `rustc --explain E0282`.
error: could not compile `no_type_annotations` due to previous error
你将看到其他数据类型的不同类型注解
标量类型
一个标量类型表示单一值。Rust有4种基本标量类型:整型,浮点型,布尔型,字符型。你可从其他编程语中了解到。让我转入怎样在Rust中应用吧。
-
整型
一个整型表示没有小数的数字。在第二章使用的u32就是一个整型,此类型的声明显示数值与一个32位的无符号的空间关联。下表是Rust内建的整型,我们可以使用这些变体声名一个整型变量。
长度 | 有符号 | 无符号 |
---|---|---|
8-bit | i8 | u8 |
16-bit | i16 | u16 |
32-bit | i32 | u32 |
64-bit | i64 | u64 |
128-bit | i128 | u128 |
arch | isize | usize |
每一个变体包括有符号和无符号并有显示的空间大小。小符号指此显量值可以为负数。
每个变体可以是有符号的,也可以是无符号的,并且具有显式大小。有符号和无符号是指数字是否有可能为负数——换句话说,数字是否需要有一个符号(有符号),或者它是否永远只是正数,因此可以在没有符号的情况下表示(无符号)。这就像在纸上写数字:当符号很重要时,数字会显示加号或减号;但是,当可以安全地假设该数字为正数时,它会显示没有符号。有符号数字使用二进制的补码表示形式存储。
每个有符号变体都可以存储从 -(2^(n - 1)) 到 2^(n - 1) - 1(包括 1)的数字,其中 n 是变体使用的位数。因此,i8 可以存储从 -(2^7) 到 2^7 - 1 的数字,等于 -128 到 127。无符号变体可以存储从 0 到 2^n - 1 的数字,因此 u8 可以存储从 0 到 2^8 - 1 的数字,等于 0 到 255。
此外,isize 和 usize 类型取决于运行程序的计算机的体系结构,在表中表示为“arch”:如果使用 64 位体系结构,则为 64 位,如果使用 32 位体系结构,则为 32 位。
您可以采用表 3-2 中所示的任何形式编写整数文本。请注意,可以是多个数值类型的数字文本允许类型后缀(如 57u8)指定类型。数字文本还可以使用 _ 作为可视分隔符,使数字更易于阅读,例如 1_000,其值与指定 1000 的值相同。
Table 3-2:Rust中的整型字面值
数字字符标识 | 例子 |
---|---|
Decimal | 98_222 |
Hex | 0xff |
Octal | 0o77 |
Binary | 0b1111_0000 |
Byte (u8 only) | b'A' |
那么,您如何知道要使用哪种类型的整数呢?如果你不确定,Rust 的默认值通常是很好的起点:整数类型默认为 i32。使用 isize 或 usize 的主要情况是在索引某种集合时。
整数溢出
假设您有一个 u8 类型的变量,可以保存 0 到 255 之间的值。如果尝试将变量更改为该范围之外的值(如 256),则会发生整数溢出,这可能导致以下两种行为之一。当你在调试模式下编译时,Rust 包括对整数溢出的检查,如果发生这种行为,会导致你的程序在运行时崩溃。Rust 使用术语 panic 当程序退出并出现错误时;我们将在第9章的“无法恢复的恐慌错误!”一节中更深入地讨论恐慌。
当你使用 --release 标志在发布模式下编译时,Rust 不包括对导致恐慌的整数溢出的检查。相反,如果发生溢出,Rust 会执行 two 的补码包装。简而言之,大于类型长度的可以保持的最大值的值“环绕”到类型可以容纳的值的最小值。对于 u8,值 256 变为 0,值 257 变为 1,依此类推。程序不会惊慌失措,但变量的值可能不是您期望的值。依赖整数溢出的包装行为被视为错误。
若要显式处理溢出的可能性,可以使用标准库为基元数值类型提供的以下方法族:
- 使用 wrapping_* 方法在所有模式下换行,例如wrapping_add
- 如果 checked_* 方法溢出,则返回 None 值
- 返回值和一个布尔值,指示 overflowing_* 方法是否存在溢出
- 使用 saturating_* 方法在值的最小值或最大值处饱和