变量与可变性 #

一、变量声明 #

1.1 基本声明 #

使用 let 关键字声明变量:

rust
fn main() {
    let x = 5;
    let name = "Alice";
    let pi = 3.14159;
    
    println!("x = {}", x);
    println!("name = {}", name);
    println!("pi = {}", pi);
}

1.2 类型标注 #

Rust可以自动推断类型,也可以显式标注:

rust
fn main() {
    // 自动推断
    let x = 5;              // 推断为 i32
    
    // 显式标注
    let y: i64 = 10;        // i64 类型
    let z: f64 = 3.14;      // f64 类型
    let s: &str = "hello";  // 字符串切片
    
    println!("x = {}, y = {}, z = {}, s = {}", x, y, z, s);
}

1.3 未初始化变量 #

变量必须初始化后才能使用:

rust
fn main() {
    let x: i32;
    // println!("{}", x);  // 错误:使用了未初始化的变量
    
    x = 5;
    println!("{}", x);      // 正确
}

二、不可变性 #

2.1 默认不可变 #

Rust变量默认不可变:

rust
fn main() {
    let x = 5;
    // x = 10;  // 错误:不能对不可变变量赋值两次
    
    println!("{}", x);
}

2.2 可变变量 #

使用 mut 关键字声明可变变量:

rust
fn main() {
    let mut x = 5;
    println!("x = {}", x);
    
    x = 10;  // 正确
    println!("x = {}", x);
}

2.3 不可变性的优势 #

  • 防止意外修改
  • 编译器优化
  • 线程安全
rust
fn main() {
    let data = vec![1, 2, 3, 4, 5];
    
    // 多个只读引用可以同时存在
    let r1 = &data;
    let r2 = &data;
    
    println!("{:?} {:?}", r1, r2);
}

三、常量 #

3.1 常量声明 #

使用 const 关键字声明常量:

rust
const MAX_POINTS: u32 = 100_000;
const PI: f64 = 3.14159;
const APP_NAME: &str = "MyApp";

fn main() {
    println!("Max points: {}", MAX_POINTS);
    println!("PI: {}", PI);
    println!("App: {}", APP_NAME);
}

3.2 常量与变量的区别 #

特性 常量 (const) 不可变变量 (let)
关键字 const let
类型标注 必须 可选
初始化 必须编译时常量 可以是运行时值
作用域 可以全局 只能局部
遮蔽 不允许 允许
rust
const GLOBAL_CONST: i32 = 100;  // 全局常量

fn main() {
    let runtime_value = get_value();  // 运行时值
    // const RUNTIME_CONST: i32 = get_value();  // 错误
    
    const LOCAL_CONST: i32 = 50;  // 局部常量
}

fn get_value() -> i32 { 42 }

3.3 常量表达式 #

常量必须是编译时可计算的值:

rust
const SECONDS_PER_HOUR: u32 = 60 * 60;
const BUFFER_SIZE: usize = 1024;
const MAX_NAME_LEN: usize = 100;

// 错误:函数调用不是编译时常量
// const NOW: String = String::new();

四、变量遮蔽 #

4.1 基本遮蔽 #

可以声明同名变量,新变量会遮蔽旧变量:

rust
fn main() {
    let x = 5;
    println!("x = {}", x);  // x = 5
    
    let x = "hello";
    println!("x = {}", x);  // x = hello
    
    let x = true;
    println!("x = {}", x);  // x = true
}

4.2 遮蔽与类型改变 #

遮蔽可以改变变量类型:

rust
fn main() {
    let spaces = "   ";
    println!("spaces: '{}' (string)", spaces);
    
    let spaces = spaces.len();
    println!("spaces: {} (number)", spaces);
}

4.3 遮蔽与可变性 #

遮蔽可以从不可变变为可变:

rust
fn main() {
    let x = 5;
    println!("x = {}", x);
    
    let mut x = x + 1;
    x += 10;
    println!("x = {}", x);
}

4.4 遮蔽 vs 可变 #

rust
fn main() {
    // 使用遮蔽
    let spaces = "   ";
    let spaces = spaces.len();
    
    // 使用可变变量(类型不同时无法使用)
    // let mut spaces2 = "   ";
    // spaces2 = spaces2.len();  // 错误:类型不匹配
}

五、静态变量 #

5.1 静态变量声明 #

使用 static 关键字声明静态变量:

rust
static mut COUNTER: u32 = 0;
static APP_VERSION: &str = "1.0.0";

fn main() {
    println!("Version: {}", APP_VERSION);
    
    // 访问可变静态变量需要 unsafe
    unsafe {
        COUNTER += 1;
        println!("Counter: {}", COUNTER);
    }
}

5.2 静态变量与常量的区别 #

特性 静态变量 (static) 常量 (const)
内存位置 固定地址 内联到使用处
可变性 可以使用 mut 不可变
生命周期 'static 无生命周期概念
大小 有固定地址 可能被复制多次
rust
static mut STATE: i32 = 0;  // 全局可变状态(需要unsafe)

const MAX_SIZE: usize = 100;  // 编译时常量

六、解构声明 #

6.1 元组解构 #

rust
fn main() {
    let tuple = (1, "hello", 3.14);
    
    let (a, b, c) = tuple;
    println!("a = {}, b = {}, c = {}", a, b, c);
    
    // 忽略部分值
    let (x, _, z) = tuple;
    println!("x = {}, z = {}", x, z);
}

6.2 数组解构 #

rust
fn main() {
    let arr = [1, 2, 3, 4, 5];
    
    let [first, second, ..] = arr;
    println!("first = {}, second = {}", first, second);
    
    let [.., last] = arr;
    println!("last = {}", last);
}

6.3 结构体解构 #

rust
struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let point = Point { x: 10, y: 20 };
    
    let Point { x, y } = point;
    println!("x = {}, y = {}", x, y);
    
    // 重命名
    let Point { x: a, y: b } = Point { x: 1, y: 2 };
    println!("a = {}, b = {}", a, b);
}

七、下划线变量 #

7.1 忽略变量 #

使用 _ 忽略不需要的值:

rust
fn main() {
    let _ = some_function();  // 忽略返回值
    
    let (x, _, z) = (1, 2, 3);  // 忽略中间值
    println!("x = {}, z = {}", x, z);
}

fn some_function() -> i32 { 42 }

7.2 未使用变量前缀 #

使用 _ 前缀消除未使用警告:

rust
fn main() {
    let used = 1;
    let _unused = 2;  // 不会警告
    
    println!("{}", used);
}

7.3 __x 的区别 #

rust
fn main() {
    let _ = 5;   // 完全忽略,不会绑定
    let _x = 5;  // 绑定但未使用,值会被保留到作用域结束
    
    // println!("{}", _);   // 错误:_ 不是变量
    // println!("{}", _x);  // 正确
}

八、实践示例 #

8.1 配置管理 #

rust
const MAX_CONNECTIONS: usize = 100;
const DEFAULT_PORT: u16 = 8080;
const APP_NAME: &str = "MyServer";

fn main() {
    let mut connections = 0;
    
    println!("{} starting on port {}", APP_NAME, DEFAULT_PORT);
    
    while connections < MAX_CONNECTIONS {
        connections += 1;
        println!("Active connections: {}", connections);
    }
    
    println!("Max connections reached!");
}

8.2 状态转换 #

rust
fn main() {
    let state = "loading";
    println!("State: {}", state);
    
    let state = "ready";
    println!("State: {}", state);
    
    let state = state.len();
    println!("State name length: {}", state);
}

九、总结 #

本章学习了:

  • 变量声明与类型标注
  • 不可变性与 mut 关键字
  • 常量 const 的使用
  • 变量遮蔽机制
  • 静态变量
  • 解构声明
  • 下划线变量的使用

Rust的变量系统是其安全性的重要组成部分。下一章,我们将学习基本数据类型。

最后更新:2026-03-27