第一章(下):数据类型--告别“number”一把梭

Unknown Author 独酌
2025-11-16 Rust, Book

在 TypeScript/JavaScript 中,我们定义数字通常极其简单:

1
2
3
// TS
let age: number = 25;
let salary: number = 10000.50;

不管是整数、小数、正数、负数,TS 统统用number搞定(实际上是双精度浮点数)。

但在 Rust 里,为了追求极致的性能和内存控制,这就不够用了。Rust 要求你把数据放进最合适的格子里。

我们先来看看最常用的两种数字类型:

  1. 有符号整数 (Signed Integers):i 开头(integer)。

    • 可以存负数

    • 例如:i32 (32位整数, Rust 的默认整数类型), i64, i8等。

  2. 无符号整数 (Unsigned Integers):u 开头(unsigned)。

    • 只能存正数(和零)。

    • 例如:u32, u64, u8 等。

💡 记忆口诀:i 是包含负数 (internet 喷子多,有负能量),u 是只有正数 (you are positive, 你很正能量)。

类型系统的“严格” (Strictness)

在这里,我们需要聊聊 Rust 和 TypeScript 最大的不同。

在 TS 里,你可能习惯了这种操作(虽然不推荐,但它是合法的 JS):

1
2
3
4
5
// TypeScript
let age: number = 25;
let year: number = 2023;
// 只要都是 number,随便减
let birth = year - age;

但是在 Rust 里,类型检查是极其严格的。就算它们都是“数字”,如果“位宽”或“符号”不一样,它们就不能直接进行运算。

来看看这段代码:

1
2
3
4
5
6
7
8
9
fn main() {
let age: u8 = 25; // 你选择的 u8
let year: i32 = 2023; // 默认是 i32

// 试图把 u8 和 i32 相减
let birth_year = year - age;

println!("出生年份: {}", birth_year);
}

由于 ageu8,而 yeari32,Rust 编译器会报错,拒绝编译。它不会像 JS 那样自动帮你转换类型。

挑战: 为了让这段代码跑通,我们需要把 age 转换成和 year 一样的类型。在 Rust 中,我们使用 as 关键字来进行显式类型转换。

你能猜出怎么修改 let birth_year = year - age; 这一行吗?

(提示:这有点像 TypeScript 的 as number,但你需要指定具体的 Rust 类型)

答案

1
let birth_year = year - age as i32;

通过 as i32,你显式地把 u8 类型的 age 转换成了 i32,这样它就可以和 year 愉快地相减了。

💡这里的关键点

  • 显式转换 (Explicit Casting): JavaScript 经常会在后台偷偷帮你做类型转换(比如字符串加数字),这被称为“隐式转换”。Rust 为了安全,拒绝任何隐式转换。如果你想变,你必须用代码(as)画押签字。

  • 安全隐患: 虽然 u8i32 是安全的(小盒子装进大盒子),但反过来(大转小)可能会导致数据截断(Truncation)。Rust 把这个控制权交给了你,这意味着你得清楚自己在做什么。

🎉第一章通过!

恭喜你完成了 Rust 基础的第一步。我们这一章学到了:

  1. 变量默认不可变 (let),想改要加 mut

  2. 类型更细分 (i32 vs u8),根据数据实际情况选择“容器”。

  3. 严苛的运算规则,不同类型不能直接算,必须手动 as

独酌

独酌

小镇码农

相关文章