变量和可变性
变量和可变性
rust
let a = 123; // 不可变变量
let mut b = 10; // 可变变量- Rust 默认不可变
- 可选择性指定类型
mut修饰变量绑定,而不是类型- 不可变变量无法重新赋值
let语句只能在函数体或代码块内部使用,用于创建局部变量
常量 constants
- 用于定义在编译时就确定的值,不可更改(常用)
rust
const AGE: i32 = 123;- 全局变量
- 声明时必须指定类型
- 不能使用
mut - 必须是编译期常量(表达式)
- 变量名全大写
静态变量 static
- 名称采用
SCREAMING_SNAKE_CASE写法 - 指向内存中固定的地址,在整个程序的生命周期内都存在.
- 如果需要修改(不推荐且不安全),必须配合
mut和unsafe块
rust
static A: i32 = 123;
static mut B: i32 = 123; // Unsafe- 有固定内存地址
- 生命周期(
'static)贯穿整个程序 - 通常用于全局变量
遮蔽 shadowing
rust
let a = 123; // 不可变变量
let a = a + 1; // 变量遮蔽
const A: i32 = 10;
fn main() {
const A: i32 = 20; // ✅ 允许 shadowing
}- 重新创建新变量,只是碰巧和原来的变量名一样
- 允许改变类型
- 与
mut不同 - 本质不是覆盖,覆盖会修改原地址中的值,发生遮蔽时只是指针指向新的值,原值依旧存在,只是无法通过变量找到原值了
覆盖(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 调用或全局状态).
- 数据量非常大,不希望因多次内联而导致程序体积膨胀.
- 需要使用
Mutex或Atomic等实现全局可变状态.