文章

Rust 数据类型

Rust

Rust 数据类型

Rust 数据类型

数据类型

在 Rust 中,每一个值都是一个数据类型。这告诉了 Rust 它被指定为何种数据,以便更好地明确数据处理方式。

数据类型有两个子集:标量(scalar)和复合(compound)

标量类型

标量类型代表一个单独的值,在 Rust 中,有 4 种基本的标量类型:

  • 整型
  • 浮点型
  • 布尔型
  • 字符类型

整型

数字类型默认为 i32

长度有符号无符号
8-biti8u8
16-biti16u16
32-biti32u32
64-biti64u64
128-biti128u128
archisizeusize

每一个变体都是有符号或无符号的,并且一定有值。

有符号位的变体可以存储 -(2^(n - 1))2^(n - 1) - 1 的数字,无符号位的变体可以存储 02^n - 1 的数字。

isizeusize 类型是依赖于运行程序的计算机架构,比如 64 位架构上它们就是 64 位的,32 位架构上它们就是 32 位的。

多种数字类型的数字字面值允许使用类型后缀,如 66i8

整型溢出

Rust 也会出现整型溢出的问题

  • 当在 debug 模式下编译代码时,会出现整型溢出的 panic
  • 而在 release 模式下编译代码时,不会出现整型溢出的 panic ,在这种模式下 Rust 会进行一种 二进制补码 的操作,即比此类型能容纳的最大值还大的值会绕回到最小值,如最大值为 256,此时值被绑定为 266,那么此时这个值会变为 0,以此类推。这种方式就能够解释了为什么 Rust 在 release 模式下编译代码时不会出现整型溢出的 panic 了。但是随之而来的问题是,变量可能也不会得到你期望的值了。
  • 显式地解决整型溢出的错误的办法,可以使用以下几种标准库提供的原始数字类型方法:
    • wrapping_* 方法
    • checked_* 方法
    • overflowing_* 方法
    • saturating_* 方法

浮点型

浮点型默认为 f64。所有的浮点型都是有符号的。

Rust 中有两个浮点数类型:f32f64

fn main() {
  let x = 64.0; // f64
  let y: f32 = 32.0; // f32
}

布尔型

Rust 中有两个布尔型:truefalse,使用 bool 表示类型。

fn main() {
  let t = true;
  let f: bool = false;
}

字符类型

使用 char 表示字符类型

fn main() {
  let c = 'z';
  let str: char = 'char';
}

⚠️:使用单引号声明 char 字面量,双引号声明的是字符串字面量。

复合类型

复合类型是将多个值组合成一个类型,Rust 有两个原生类型:数组、元组。

元组

元组是一个将多个其他类型的值组合进一个复合类型的主要方式。

元组的长度一旦固定,其长度不会增大或缩小,和其他语言一样。

fn main() {
  let tuple: (i32, f64, u8) = (123, 32.1, 1);
}

从元组中获取单个值,可以使用模式匹配来解构元组。

fn main() {
  let tuple = (123, 32.1, 1);
 
  let (x, y, z) = tuple;
 
  println!("The value of x is: {x}"); // 123
}

也可以使用 . 加 值的索引方式来获取单个值。

fn main() {
  let tuple = (123, 32.1, 1);
 
  let x = tuple.0;
 
  let y = tuple.1;
 
  let z = tuple.2;
}

不带任何值的元组,被称为单元元组,值和对应的类型都写为 ()

fn main() {
  let tuple: () = ();
}

数组

与其他语言一样,数组类型也是要求数组中元素的类型保持一致。有点不同的是,Rust 中的数组长度是固定的,也就是说长度不可变。

fn main() {
  let a = [111, 222, 333];
}

想要在栈空间上分配空间或固定保有元素的数量时,数组非常适合。但数组没有 vector 类型灵活。

vector 类型是标准库提供的一个允许增长或减少长度的类似于数组的集合类型。

可以这样写数组类型,方括号包含每个元素的类型,后跟数组元素的数量。

let arr: [i32, 5] = [1, 2, 3, 4, 5];

你也可以在方括号中指定初始值并再加元素个数来创建一个每个元素都为相同值的数组:

let arr = [3;5]; // 等价于 [3, 3, 3, 3, 3]

当尝试用索引访问一个元素时,Rust 会检查指定的索引是否小于数组的长度。如果索引超出了数组长度,Rust 会 panic

这种错误处理机制使程序既不会 panic 也不会导致非法内存访问。