Skip to content

变量和可变性

变量和可变性

rust
let a = 123;  // 不可变变量
let mut b = 10; // 可变变量
  1. Rust 默认不可变
  2. 可选择性指定类型
  3. mut 修饰变量绑定,而不是类型
  4. 不可变变量无法重新赋值
  5. let 语句只能在函数体或代码块内部使用,用于创建局部变量

常量 constants

  • 用于定义在编译时就确定的值,不可更改(常用)
rust
const AGE: i32 = 123;
  1. 全局变量
  2. 声明时必须指定类型
  3. 不能使用 mut
  4. 必须是编译期常量(表达式)
  5. 变量名全大写

静态变量 static

  • 名称采用 SCREAMING_SNAKE_CASE 写法
  • 指向内存中固定的地址,在整个程序的生命周期内都存在.
  • 如果需要修改(不推荐且不安全),必须配合 mutunsafe
rust
static A: i32 = 123;
static mut B: i32 = 123;  // Unsafe
  1. 有固定内存地址
  2. 生命周期('static)贯穿整个程序
  3. 通常用于全局变量

遮蔽 shadowing

rust
let a = 123;  // 不可变变量
let a = a + 1;  // 变量遮蔽

const A: i32 = 10;
fn main() {
    const A: i32 = 20; // ✅ 允许 shadowing
}
  1. 重新创建新变量,只是碰巧和原来的变量名一样
  2. 允许改变类型
  3. mut 不同
  4. 本质不是覆盖,覆盖会修改原地址中的值,发生遮蔽时只是指针指向新的值,原值依旧存在,只是无法通过变量找到原值了

覆盖(Mutation): 同一个坑位,换个东西填进去.

遮蔽(Shadowing): 在旁边挖个新坑,把原来的坑给挡住,让人看不见.

const 和 static 的区别

  • const 是为了"给值取个名字", 会被硬编码到程序中
  • static 是为了"开辟一块持久的全局空间",有固定内存地址

核心区别对比

特性const (常量)static (静态变量)
内存位置没有固定地址.在使用处被"内联"(Inline)替换.固定内存地址.在程序运行期间占据唯一的内存位置.
可变性永远不可变.可以使用 static mut,但读写均需 unsafe 块.
生命周期没有生命周期(类似宏展开的值).拥有 'static 生命周期(贯穿程序始终).
trait 关联可以作为 trait 的关联项(Associated Item).不能作为 trait 的关联项.
泛型支持支持泛型常量.不支持泛型.

内存行为直观理解

  • const 像"复制粘贴": 编译器会将 const 的值直接硬编码到调用它的二进制指令中.这意味着如果你定义了一个很大的 const 数组并在多处使用(每处都会被硬编码),可能会导致程序体积变大.
  • static 像"全局坐标": 程序中所有引用该变量的地方都指向同一个内存地址.它在内存的 Data 段中只存在一份数据.

如何选择?

  • 优先选 const: 对于普通配置参数、数学常数、数组长度等,const 性能更好且更安全,因为它允许编译器进行更多优化.
  • static 的场景:
  • 需要固定内存地址(如: FFI 调用或全局状态).
    • 数据量非常大,不希望因多次内联而导致程序体积膨胀.
    • 需要使用 MutexAtomic 等实现全局可变状态.

基于 MIT 协议发布