数据类型
在 Rust 中,每一个值都是一个数据类型。这告诉了 Rust 它被指定为何种数据,以便更好地明确数据处理方式。
数据类型有两个子集:标量(scalar)和复合(compound)
标量类型
标量类型代表一个单独的值,在 Rust 中,有 4 种基本的标量类型:
- 整型
- 浮点型
- 布尔型
- 字符类型
整型
数字类型默认为 i32
。
长度 | 有符号 | 无符号 |
---|---|---|
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
的数字,无符号位的变体可以存储 0
到 2^n - 1
的数字。
isize
和 usize
类型是依赖于运行程序的计算机架构,比如 64 位架构上它们就是 64 位的,32 位架构上它们就是 32 位的。
多种数字类型的数字字面值允许使用类型后缀,如 66i8
。
整型溢出
Rust 也会出现整型溢出的问题
- 当在
debug
模式下编译代码时,会出现整型溢出的panic
- 而在
release
模式下编译代码时,不会出现整型溢出的panic
,在这种模式下 Rust 会进行一种二进制补码
的操作,即比此类型能容纳的最大值还大的值会绕回到最小值,如最大值为256
,此时值被绑定为266
,那么此时这个值会变为0
,以此类推。这种方式就能够解释了为什么 Rust 在release
模式下编译代码时不会出现整型溢出的panic
了。但是随之而来的问题是,变量可能也不会得到你期望的值了。 - 显式地解决整型溢出的错误的办法,可以使用以下几种标准库提供的原始数字类型方法:
wrapping_*
方法checked_*
方法overflowing_*
方法saturating_*
方法
浮点型
浮点型默认为 f64
。所有的浮点型都是有符号的。
Rust 中有两个浮点数类型:f32
和 f64
。
布尔型
Rust 中有两个布尔型:true
和 false
,使用 bool
表示类型。
字符类型
使用 char
表示字符类型
⚠️:使用单引号声明 char
字面量,双引号声明的是字符串字面量。
复合类型
复合类型是将多个值组合成一个类型,Rust 有两个原生类型:数组、元组。
元组
元组是一个将多个其他类型的值组合进一个复合类型的主要方式。
元组的长度一旦固定,其长度不会增大或缩小,和其他语言一样。
从元组中获取单个值,可以使用模式匹配来解构元组。
也可以使用 .
加 值的索引方式来获取单个值。
不带任何值的元组,被称为单元元组,值和对应的类型都写为 ()
。
数组
与其他语言一样,数组类型也是要求数组中元素的类型保持一致。有点不同的是,Rust 中的数组长度是固定的,也就是说长度不可变。
想要在栈空间上分配空间或固定保有元素的数量时,数组非常适合。但数组没有 vector
类型灵活。
vector
类型是标准库提供的一个允许增长或减少长度的类似于数组的集合类型。
可以这样写数组类型,方括号包含每个元素的类型,后跟数组元素的数量。
你也可以在方括号中指定初始值并再加元素个数来创建一个每个元素都为相同值的数组:
当尝试用索引访问一个元素时,Rust 会检查指定的索引是否小于数组的长度。如果索引超出了数组长度,Rust 会 panic
。
这种错误处理机制使程序既不会 panic
也不会导致非法内存访问。