Rust中的Immutable与const:有什么区别?2025指南

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

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

开始课程

Rust中的不可变变量与常量:为什么即使是经验丰富的开发者也会困惑?

\n\n

你是否曾在编写Rust代码时突然想到:“等等,我用let声明了一个变量,它是不可变的。而const也是一种常量。那么它们有什么区别呢?”如果你有过这样的疑问——你并不孤单。在Stack Overflow上,问题“Rust中不可变变量和常量有什么区别?”被浏览了数千次。这并非巧合。

\n\n

乍一看,let x = 5和const X: i32 = 5似乎做的是同一件事:它们都防止值的更改。但在Rust——这一将内存安全和性能置于首位的语言中,魔鬼藏在细节里。在2025年,理解这些细节不仅是理论问题,更是编写高效、地道代码的必要条件。

\n\n

在本文中,我们将彻底搞清楚:不可变变量与常量有何不同,何时使用什么,以及当前有哪些最佳实践。让我们开始吧!

\n\n

1. 基本理解:编译器是怎么说的?

\n\n

让我们从最简单的地方开始。在Rust中,变量默认是不可变的。这意味着在赋值之后,你不能覆盖它。

\n\n
fn main() {\n    let x = 5;\n    // x = 6; // 错误!不能修改不可变变量\n    println!("x = {}", x);\n}
\n\n

这是常量的一个例子:

\n\n
const MAX_POINTS: u32 = 100_000;\n\nfn main() {\n    println!("MAX_POINTS = {}", MAX_POINTS);\n}
\n\n

从表面上看——它们很相似。但Rust编译器对它们的处理方式完全不同。而有趣的部分就从这里开始了。

\n\n

1.1. 关键区别 #1:它们驻留在哪里?

\n\n
    \n
  • let——声明一个变量。它存在于栈(或堆,如果是Box、String等)上,并拥有一个内存地址。你可以获取它的引用、将其传递给函数、移动它。
  • \n
  • const——声明一个常量。它没有固定的内存地址。编译器会在使用点将其值内联到代码中。
  • \n
\n\n

这是一个根本性的区别。const不是变量;它是一个在编译时被替换的命名值。

\n\n
fn main() {\n    let x = 42;\n    let y = &x; // 正常,获取变量的引用\n\n    const Z: i32 = 100;\n    // let w = &Z; // 错误!常量没有地址,无法获取引用\n}
\n\n

2. 深入探讨:性能与语义

\n\n

现在我们知道了“驻留位置”,让我们来分析其他重要方面。

\n\n

2.1. 生命周期与作用域

\n

常量存在于全局作用域(或函数内部,但具有static生命周期)。它们在程序的整个运行期间都存在。可以在函数外部声明,并在任何地方访问。

\n\n

不可变变量仅存在于块(函数、循环、if)内部。一旦块结束,内存就被释放。

\n\n
const GLOBAL_CONST: i32 = 10;\n\nfn main() {\n    let local_var = 20;\n    // local_var 仅存在于 main 函数内部\n}\n// local_var 不再存在\n// GLOBAL_CONST 仍然可以访问
\n\n

2.2. 类型与注解

对于const,指定数据类型是强制性的。对于let,编译器会进行推断。

const PI: f64 = 3.14159; // 强制:const NAME: Type = value;
let pi = 3.14159; // 编译器会推断出它是 f64 类型

2.3. 编译时求值(CTFE)

const的值必须在编译时可计算。

博客

书籍推荐