Skip to content

数据类型

  • 在 Rust 中,除了原生的基础类型(如 i32, f64, char, bool)和元组/数组外,几乎所有复杂的数据组织形式都是靠 structenumunion 撑起来的

标量类型

整型

语法: 类型性质 + 位数

  • 无符号: 02^n - 1
  • 有符号: -2^(n-1)2^(n-1) - 1
长度无符号有符号范围
8-bitu8i80-255-128-127
16-bitu16i160-65,535-32,768-32,767
32-bitu32i32(默认)0-约 42.9 亿约 -21.4 亿-21.4 亿
64-bitu64i640-1.84 x 10^19-9.22 x 10^18-9.22 x 10^18
128-bitu128i128
架构相关usizeisize
  • i 代表 Integer(整数),特指 Signed Integer(有符号整数).它可以表示正数、负数和零.
  • u 代表 Unsigned(无符号),特指 Unsigned Integer(无符号整数).它只能表示非负数(0 和正数).
  • 数组索引必须是 usize

整型字面值

数字字面值例子
Decimal (十进制)98_222
Hex (十六进制)0xff
Octal (八进制)0o77
Binary (二进制)0b1111_0000
Byte (单字节字符,仅限于u8)b'A' = 65

整数溢出

rust
let x: u8 = 255;
let y = x + 1;

// Debug模式 会 panic
// Release模式 会变成 0

字面量后缀类型标注

rust
let x = 10u8; // 等于 let x: u8 = 10;
let y = 20i64; // 等于 let y: i64 = 20;
let z = 3.14f32; // 等于 let z: f32 = 3.14;

浮点型

长度类型精度范围
32-bitf32 单精度浮点数约 6 ~ 9 位-1.18*10^38-3.40*10^38
64-bitf64 双精度浮点数(默认)约 15 ~ 17 位-2.23*10^308-1.79*10^308
  • f32: 占用 32 位(4 字节).
  • f64: 占用 64 位(8 字节),正好是 f32 的两倍.

例子: 如果你计算圆周率,f32 可能只能精确到 3.141592,而 f64 能到 3.141592653589793

布尔类型 bool

  • truefalse 是仅有的两个值
  • 占 1 字节(8 bit)
rust
let t = true;
let f: bool = false;

if true { }     // ✅
if 1 { }        // ❌ 不允许,整数不能作为布尔条件;Rust 不会将整数隐式转换为 bool
if 1 != 0 { }   // ✅ 需要显式比较
  • 布尔值可以通过比较运算符(==<>等)生成
  • 布尔值可以通过逻辑运算符(&&||!)组合
rust
let x = 5;
let y = x > 3 && x < 10; // y = true

字符类型 char

char 类型是语言中最原始的字母类型

  • 是一个 Unicode 标量值(Unicode scalar value)
  • 占 4 字节(32 bit)
  • 使用单引号 '' 声明
rust
let z: char = 'ℤ'; // with explicit type annotation
let c = 'A';   // 1 字节表示,但占 4 字节内存
let emoji = '😻'; // 也是 4 字节

char 与 String 的区别

特性charString
声明符号单引号 ''双引号 ""
存储内容单个字符字符序列
大小固定 4 字节动态(堆分配)
类型性质原始类型复杂类型
Unicode表示单个码位多个码位序列

复合类型

Rust 有两个原生的复合类型: 元组(tuple)和数组(array)

元组 tuple

  • 将多个不同类型的值组合进一个复合类型的主要方式
  • 元组长度是固定的
  • 元组每个元素的所有权是独立的
  • 本质是一个没有名字的结构体
rust
let tup: (i32, f64, u8) = (500, 6.4, 1);
let (x, y, z) = tup; // 模式匹配取值: 解构(destructuring)
let first = tup.0; // 点号(.)取值

let mut tup1 = (1, 2, 3);
tup1.0 = 10; // ✅ 可以改变元组值

空元组

Rust 的"单元类型"(unit type),使用 () 表示,等价于 JavaScript 的 undefined,很多函数默认返回它.

rust
let unit: () = ();

数组 array

  • 数组中的每个元素的类型必须相同
  • 数组长度是固定的
  • 数组的所有权是整体的
rust
let a = [1, 2, 3, 4, 5];
let a: [i32; 5] = [1, 2, 3, 4, 5];
let a = [3; 5]; // 等于 let a = [3, 3, 3, 3, 3];

let first = a[0]; // [] 取值
let mut a = [1, 2, 3];
a[0] = 10; // ✅ 可以改变元素值

数组与向量的区别

特性arrayVec(向量)
长度固定动态
内存分配
语法[T; n]Vec<T>
索引usize 类型usize 类型
越界行为panicpanic

额外补充

as 基本类型转换

Rust 不会自动进行类型转换,需要使用 as 关键字显式转换.截断和溢出行为由目标类型决定:

rust
let x: i32 = 42;
let y = x as f64;      // i32 → f64
let z = 3.99f64 as i32; // f64 → i32,截断小数部分 → 3(不四舍五入)
let b = 300u32 as u8;   // 超出范围时截断(300 % 256 = 44)

let c = 'A' as u32;    // char → u32(Unicode 码位: 65)
let d = 65u8 as char;  // u8 → char → 'A'

as 只能用于基本数值类型和 char/指针之间的转换,不能用于 String/&str 等复杂类型(需用 .to_string()/.parse() 等方法).

isizeusize

  • isize/usize 的大小取决于目标平台的指针宽度: 32位系统为4字节,64位系统为8字节.
  • usize数组索引和集合长度的标准类型(len()[] 索引均返回/接受 usize).
  • isize 常用于指针偏移量计算(负偏移时派上用场).

整数溢出的安全处理方法

除了 Debug 模式 panic / Release 模式截断外,标准库提供了四组安全方法:

  • checked_add() : 安全加法,溢出时返回 None,适合需要明确处理溢出情况的场景
  • saturating_add() : 饱和加法,溢出时结果固定在该类型的最大值或最小值,适合需要边界保护的场景
  • wrapping_add() : 环绕加法,溢出时按二进制环绕处理,行为与 Release 模式一致,适合需要循环计数的场景
  • overflowing_add() : 返回元组 (result, is_overflow),同时获得结果和溢出标志,适合需要记录溢出事件的场景

使用建议: 根据具体需求选择合适的方法,优先考虑 checked_add() 以获得更好的错误处理能力.

rust
let x: u8 = 255;
x.checked_add(1)      // → None(溢出返回 None)
x.saturating_add(1)   // → 255(饱和: 钉在最大/最小值)
x.wrapping_add(1)     // → 0(环绕: 和 Release 行为一致)
x.overflowing_add(1)  // → (0, true)(返回结果和是否溢出的元组)

基于 MIT 协议发布