Skip to content

在rust中,数据类型分为两大类:

标量类型:代表一个单一的值。

复合类型:可以把多个值组合成一个类型。

Rust 是一门静态类型语言,也就是说,所有变量的类型在编译期就必须完全确定。通常编译器能通过你的代码自动推断类型,但一旦出现歧义,你就必须手工标注类型。

rust
let guess: u32 = "42".parse().expect("Not a number!");// 这里必须标明 u32 因为rust无法推断出来

另外,Rust 的类型是强类型的,不会悄悄做隐式类型转换(比如把一个整数自动转成浮点数)。你要是想转,必须用 as 或用 From/Into 等 trait 显式转换。

标量类型 ​

标量类型表示单一值。Rust 有四种基本标量类型:整型、浮点型、布尔型、字符型。

1. 整型(Integer) ​

整型是最常用的数字类型,Rust 按长度和有无符号分成很多种:

长度有符号无符号
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
架构相关isizeusize

isize 和 usize 在 64 位机器上就是 64 位,在 32 位机器上是 32 位,主要用于集合的索引和长度。

默认的整数类型是 i32,性能和兼容性平衡得最好。

整数字面量可以写成多种进制,还能加下划线提升可读性:

rust
let a = 98_222;          // 十进制
let b = 0xff;            // 十六进制
let c = 0o77;            // 八进制
let d = 0b1111_0000;    // 二进制
let e = b'A';            // 字节字面量 (u8)

2. 浮点型(Floating-Point) ​

Rust 有 f32(单精度)和 f64(双精度)两种。默认是 f64,因为在现代 CPU 上速度和 f32 差不多,但精度更高。

rust
let x = 2.0;      // f64
let y: f32 = 3.0; // f32

浮点数遵循 IEEE-754 标准。注意,它不能直接判等——这点和所有语言一样,精度问题会导致 0.1 + 0.2 != 0.3。如果需要更精确的小数运算,请用 rust_decimal 或 num-rational 等 crate。

3. 布尔型(Boolean) ​

和别的语言一样,bool 只有两个值:true 和 false,占用一个字节。

rust
let is_rust_fun: bool = true;

它是条件判断的基石,Rust 不会把非布尔值自动转成布尔,比如 if 1 {} 在 Rust 中是编译错误,必须写 if 1 != 0 {}。

4. 字符类型(Char) ​

Rust 的 char 有点特别:它4 字节,代表一个 Unicode 标量值,范围从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF。这意味着它能表示中文、emoji 等任何单个字符。

rust
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';

注意 char 用的是单引号,字符串用双引号。它们不能混用,这一点编译器会非常严格地提醒你。

复合类型 ​

复合类型可以把多个值“打包”成一个类型。Rust 里最原始的两个复合类型是元组(tuple)和数组(array)。

元组(Tuple) ​

元组是把不同类型的几个值组合成一个整体的通用方式,长度固定。

rust
let tup: (i32, f64, u8) = (500, 6.4, 1);

解构元组很方便:

rust
let (x, y, z) = tup;
println!("y 的值是: {y}");

也可以用句点索引直接访问:

rust
let five_hundred = tup.0;
let six_point_four = tup.1;

没有任何动态索引,类型完全不同时,编译器会保证你不会弄混。

元组特殊值:单元(unit),空元组 (),表示没有值。如果一个函数不返回值,它实际上返回的就是 ()。

2. 数组(Array) ​

数组要求每个元素类型相同,而且长度固定,在栈上分配。它和 vector(Vec<T>,可变长,在堆上)不同。

rust
let a = [1, 2, 3, 4, 5];
let months = ["一月", "二月", "三月", ...];

你可以显式指定类型和长度:

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

用方括号初始化为相同值:

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

数组访问:

let first = a[0];

越界保护:如果你尝试用 a[10] 访问一个长度为 5 的数组,Rust 在运行时会做边界检查,一旦越界直接 panic,而不是像 C 那样默默读写非法内存。这是 Rust 内存安全保障的重要体现。

在需要动态调整大小的场景,应该使用 Vec<T>,但当你明确知道元素数量不变时(比如一周七天、十二个月),数组就是更高效、更安全的选择。

Java · Golang · Rust