usize vs u32 在 Rust 中:区别与选择

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

usize vs u32:Rust 整数类型的对决



如果你写 Rust 至少一周,你肯定遇到过这种情况:编译器报错,因为你试图用 u32 索引向量,而它要求 usize。或者反过来——你把 usize 传给一个期望 u32 的函数,然后在 IDE 中看到一片红色波浪线。



在 Stack Overflow 上,问题 “usize 和 u32 有什么区别?” 获得了数千次浏览。这并非偶然——混淆这两种类型是 Rust 初学者最常见的陷阱之一。



让我们一劳永逸地弄清楚它们的区别、何时使用哪种类型,以及如何避免出错。开始吧!



简要:主要区别



usize 是一个无符号整数,其大小取决于系统架构。在 64 位系统上,它是 8 字节;在 32 位系统上,它是 4 字节。u32 则始终是 4 字节,与平台无关。



但区别不仅在于大小。关键在于语义:



  • usize 用于集合的大小、索引和元素数量
  • u32 用于不超过 40 亿的数值数据


是的,编译器不允许在没有显式转换的情况下混用它们。这不是 bug,而是特性——Rust 以此保护你免受与架构位宽相关的错误影响。



为什么存在 usize?



想象一下,你编写的代码既要能在旧的 32 位微控制器上运行,也要能在现代的 64 位服务器上运行。在 32 位系统上,向量的长度不能超过 2^32 - 1 个元素,而在 64 位系统上则是 2^64 - 1。



如果你在 64 位系统上使用 u32 进行索引,那么即使内存足够,你也无法访问超过 40 亿的元素。usize 解决了这个问题:它始终能够容纳当前架构上可能的最大内存大小。



// 示例:usize 自动适应架构fn main() {    let large_vec: Vec<u8> = vec![0; 1_000_000_000]; // 10 亿个元素        // usize 在任何平台上都能容纳这个索引    let index: usize = 999_999_999;    println!("元素: {}", large_vec[index]);        // 而 u32 在 32 位系统上可能不够用    // let bad_index: u32 = 999_999_999; // 在 32 位系统上可以编译,但...    // large_vec[bad_index as usize]; // ...必须进行转换}


表格对比



特性 usize u32
64 位系统上的大小 8 字节 4 字节
32 位系统上的大小 4 字节 4 字节
范围(64 位) 0 .. 2^64-1 0 .. 2^32-1
主要用途 索引、大小、长度 数值数据
隐式转换 无 无


何时使用 usize?



始终用于集合索引。 这几乎是一条没有例外的规则。如果你写 vec[i],其中 i 是 u32,编译器会说:“嘿,朋友,请用 usize。”



// 正确:使用 usize 作为索引fn get_element(vec: &[i32], index: usize) -> Option<&i32> {    vec.get(index)}

// 错误:用 u32 索引——必须进行转换fn get_ele

博客

书籍推荐