4. 基础数据类型:标量类型与复合类型
数据类型,说白了就是告诉编译器「这块内存我要怎么用」。Rust 是静态类型语言,每个变量在编译时就必须知道自己的类型。我刚开始学的时候觉得这很烦,后来才发现——正是这种严格,帮我挡住了无数线上 bug。
4.1 标量类型:最基础的积木
标量类型代表单个值。Rust 有四种:整数、浮点、布尔、字符。
4.1.1 整数类型
整数分有符号(i)和无符号(u),后面跟位数。比如 i32 就是 32 位有符号整数。
| 长度 | 有符号 | 无符号 |
|---|---|---|
| 8 位 | i8 | u8 |
| 16 位 | i16 | u16 |
| 32 位 | i32 | u32 |
| 64 位 | i64 | u64 |
| 128 位 | i128 | u128 |
| arch | isize | usize |
我个人习惯:默认用 i32。除非你要存超大的数,或者做底层位操作。为什么?因为 i32 在大多数 CPU 上跑得最快,而且够用。
1_000_000 比 1000000 清楚多了。
4.1.2 浮点类型
就两种:f32 和 f64。默认是 f64,因为现代 CPU 处理 f64 和 f32 速度几乎一样,但精度更高。
let x = 2.0; // f64
let y: f32 = 3.0; // f32,显式注解
我在项目中遇到过一个问题:用 f32 做累加,跑了几个小时之后误差累积到不可接受。换成 f64 就没事了。所以,除非你明确需要节省内存(比如存几百万个坐标),否则就用 f64。
4.1.3 布尔类型
就两个值:true 和 false。大小是 1 个字节。
let is_ready = true;
let is_done: bool = false;
嗯,这里要注意:Rust 不会自动把非布尔值当成布尔用。比如 if 1 { ... } 会编译报错。你得显式写 if x != 0 { ... }。刚开始可能觉得啰嗦,但想想看——这避免了 C 语言里那种 = 和 == 搞混的经典 bug。
4.1.4 字符类型
char 类型代表一个 Unicode 标量值。注意,它是 4 个字节,不是 1 个。
let c = 'z';
let z = 'ℤ';
let heart_eyed_cat = '😻';
为什么是 4 字节?因为 Unicode 字符太多了,1 个字节根本装不下。你想想看,一个 emoji 就可能占 4 个字节。Rust 的 char 能表示所有 Unicode 字符,这是很多语言做不到的。
4.2 复合类型:把积木拼起来
复合类型把多个值组合成一个。Rust 有两种基本复合类型:元组和数组。
4.2.1 元组
元组可以包含不同类型的值。长度固定,一旦声明就不能改变。
let tup: (i32, f64, u8) = (500, 6.4, 1);
访问元组元素有两种方式:
// 模式匹配解构
let (x, y, z) = tup;
println!("y 的值是:{}", y);
// 用点号加索引
let five_hundred = tup.0;
let six_point_four = tup.1;
我个人习惯用解构,代码更清晰。但如果你只需要其中一个值,用点号索引更直接。
4.2.2 数组
数组里所有元素类型必须相同。长度也是固定的。
let a = [1, 2, 3, 4, 5];
let b: [i32; 5] = [1, 2, 3, 4, 5]; // 显式注解:类型;长度
let c = [3; 5]; // 等价于 [3, 3, 3, 3, 3]
访问数组元素用索引:
let first = a[0];
let second = a[1];
这里有个关键点:Rust 会在运行时检查数组越界。如果你访问 a[10],程序会直接 panic 退出。这比 C 语言那种「越界了也不知道,继续用脏数据」要安全得多。
4.3 类型推断与注解
Rust 编译器很聪明,能根据上下文推断类型。但有时候你得帮它一把。
let guess = "42".parse().expect("不是数字"); // 报错!编译器不知道你要什么类型
let guess: u32 = "42".parse().expect("不是数字"); // 显式注解,搞定
类型推断的规则很简单:
- 如果编译器能唯一确定类型,就不需要注解
- 如果有歧义,编译器会报错,让你显式指定
- 函数签名必须显式注解参数和返回类型
你想想看,这其实是个很好的设计。既保留了静态类型的安全性,又减少了不必要的啰嗦。我个人建议:在变量声明处尽量显式注解类型。虽然编译器能推断,但写出来对代码阅读者(包括未来的你)更友好。
4.4 知识体系总览
下面这张图帮你理清本章的知识结构:
这张图把本章内容串起来了。标量类型是基础积木,复合类型是组合方式,类型推断和注解是连接你与编译器的桥梁。掌握好这些,你就有了构建复杂程序的基本功。
公众号:蓝海资料掘金营,微信deep3321