首页 / Rust 入门教程 / 标量类型:整数与浮点数

Rust 入门教程

标量类型:整数与浮点数

本教程共 78 篇 · 第 9 篇 · 更新于 2026-08-08 · 约 8 分钟阅读

RustRust 入门教程整数类型浮点数i32f64溢出标量类型

本节目标:认清 Rust 数字类型的家族谱——整数分有符号无符号、定宽与自适应,浮点分 f32/f64,并学会正确写出各种进制的数字字面量。

Rust 是静态类型语言,每个值都有明确类型。类型分两大类:标量(scalar,单个值)和复合(后面讲)。标量里最常用的是数字,这一章专门拆整数和浮点数。

9-1 整数家族总览

整数就是没有小数部分的数字。Rust 把整数按”有无符号”和”占多少位”分成一串:

长度有符号无符号
8 位i8u8
16 位i16u16
32 位i32u32
64 位i64u64
128 位i128u128
自适应isizeusize

i 是 signed integer(有符号),能存负数;u 是 unsigned(无符号),只能存 0 和正数。i32 就是”32 位有符号整数”。

Note

有符号数的范围是 -2^(n-1)2^(n-1)-1。比如 i8 是 -128 到 127。无符号 u8 是 0 到 255。超出范围就”溢出”,下面会讲后果。

9-2 isize 和 usize 是什么

这两个比较特殊,长度取决于你跑程序的机器:32 位系统上是 32 位,64 位系统上是 64 位。它们通常用来当”索引”或”长度”——比如数组有几个元素、循环跑了多少次。你以后会看到 for i in 0..n 里的 i 多半是 usize

日常写普通数字,如果不指定,Rust 默认推断成 i32。这几乎总是够用,所以新手不用纠结,让编译器选 i32 就行。

9-3 各种进制的字面量写法

数字不只能写十进制,Rust 支持多种进制前缀:

let decimal = 98_222;      // 十进制,下划线方便读数
let hex = 0xff;            // 十六进制,255
let octal = 0o77;          // 八进制,63
let binary = 0b1111_0000;  // 二进制,240
let byte = b'A';           // 字节字面量,只能是 u8,值是 65

b'A' 这种写法只适用于 ASCII 字符,结果类型是 u8,表示字符 A 的 ASCII 码 65。其它进制都用 0x / 0o / 0b 前缀区分。

9-4 显式标注类型

当你想强制某个具体类型,用后缀:

let x = 5u8;     // 明确是 u8
let y: i64 = 10; // 冒号标注
let z = 3.14f32; // 浮点也能标

类型后缀紧跟在字面量后面,适合在类型推断不符合预期时纠正。

9-5 整数溢出:Debug 和 Release 表现不同

这是个容易栽跟头的地方。想象一个 u8 变量值是 255,你再给它加 1:

let mut num: u8 = 255;
num += 1;
  • debug 模式(你平时 cargo run / cargo build),Rust 会直接 panic(程序崩溃),并打印溢出错误。这是为了在开发时尽早暴露问题。
  • release 模式cargo build --release),Rust 采用”二进制补码回绕”:255 + 1 变成 0,不报错,但结果可能不符合你的预期。
Warning

千万别依赖”溢出回绕”当正常逻辑。它只是 release 下的一种 undefined-ish 行为,debug 下会崩。正确做法是写代码时保证数值不越界,比如用更大的类型(i64 代替 i32),或先做范围检查。

9-6 浮点数:f32 与 f64

带小数或很大/很小的数用浮点。Rust 有两种:

  • f32:单精度,占 32 位,范围小、精度低。
  • f64:双精度,占 64 位,范围大、精度高。

默认推断是 f64,因为现代 CPU 上它和 f32 速度差不多,但精度更好:

let x = 2.0;    // f64
let y: f32 = 3.0; // 显式 f32
Note

浮点数遵循 IEEE 754 标准。它有个著名特性:不能精确表示某些小数(比如 0.1 + 0.2 不等于 0.3)。做金额这类要求精确的场景,别用浮点,后面进阶会讲用专门的小数类型。新手先知道”浮点有误差”就够了。

9-7 数字运算

四则运算和别的语言一样:+ - * / %。注意整数相除会截断小数:

let a = 5 / 2; // 结果是 2,不是 2.5
let b = 5 % 2; // 取余,结果是 1

想保留小数,得先转成浮点:

let c = 5.0 / 2.0; // 2.5

9-8 怎么选数字类型

给你一个偷懒口诀:不指定时让编译器默认(整数 i32、浮点 f64);需要表示数量/索引时用 usize;明确知道数值范围小且想省内存(比如处理图像像素用 u8)再考虑定宽类型。绝大多数业务代码,i32 / u32 / f64 打天下就够。

Tip

新手最常见的编译错误之一是”类型不匹配”:比如把一个 u8 传给期望 i32 的函数。遇到这种,看报错提示补一个 as 转换(如 x as i32),但转换前先确认不会溢出。

9-9 实际写代码怎么选数字类型

讲了这么多类型,落到日常怎么选?给你省心默认:不写类型标注,让编译器推断(整数默认 i32、浮点默认 f64)。绝大多数业务逻辑用这两种就够,既不会溢出(i32 范围约 ±21 亿)也够精确。

什么情况才换类型?第一,做索引或长度时用 usize,因为它和容器、循环下标的类型天然匹配,能避免转换报错。第二,处理二进制数据(图片像素、网络协议、文件格式)时用 u8 表示单字节最自然。第三,确定数值范围很小且要存很多(比如百万级传感器读数),用 i16 省内存。第四,数值可能超过 i32(比如计数到几十亿),用 i64

Warning

不同整数类型之间不能直接运算,比如 i32i64 会编译报错,需要时用 as 转换(如 x as i64)。但 as 转换在溢出时不会 panic、会静默截断,所以只在确认安全时用;涉及用户输入或边界值时先检查范围。浮点转整数也是截断小数、不是四舍五入,想要四舍五入用标准库的舍入方法。

9-10 类型推断小测验

做个小测验巩固类型推断:下面每行 x 编译器推断成什么类型?

let x = 5;       // i32
let x = 5.0;     // f64
let x = 5u8;     // u8(后缀标注)
let x: i64 = 5;  // i64(冒号标注)

前两个靠”默认推断”(整数 i32、浮点 f64),后两个靠你显式标注。记住这个默认,写代码时大多数情况可以省掉类型标注,让编译器替你定,代码更干净。

Warning

当两种类型混在一行(如 let x = 5 + 5.0;),编译器会因”整数加浮点”直接报错,因为它不替你隐式转换。这时要显式统一,比如 let x = 5.0 + 5.0;。Rust 不做隐式数值转换,这是刻意的——避免精度意外丢失。

9-11 更安全的转换:TryFrom

前面提过 as 转换在溢出时会静默截断,不够安全。标准库还有个 TryFrom trait,能做”可能失败”的转换并返回 Result,让你显式处理转不过去的情况:let small: u8 = big.try_into().unwrap_or(255); 超范围时兜底为 255。try_into() 返回 Result,成功给值、失败给错误,比 as 的”闷声截断”安全。

Note

asTryFrom 的区别,本质是”你愿不愿意面对转换可能失败”。练习里用 as 图快无妨;写涉及用户输入、边界值的正式代码时,用 TryFrom 把失败显式摊开,程序更健壮。这也是 Rust “把错误摆在明处”的一贯风格。

9-12 小结

整数分有符号 i / 无符号 u,宽度从 8 到 128 外加自适应 isize/usize;浮点是 f32/f64。记住溢出在 debug 下会崩、浮点有误差、整数除法会截断。下一章看剩下的两个标量类型:布尔和字符。