Skip to content

高级特性

> 探索变量遮蔽(Shadowing)特性,理解其与 mut 可变变量的本质区别。

变量遮蔽(Shadowing)

基本概念

rust
fn main() {
    let x = 5;
    let x = x + 1;  // 遮蔽之前的 x
    let x = x * 2;  // 再次遮蔽

    println!("x = {}", x);  // 输出 12
}
▶ Run

遮蔽 vs 可变

rust
fn main() {
    // 使用 mut
    let mut y = 5;
    y = y + 1;  // 修改原值
    y = y * 2;
    println!("y = {}", y);  // 12

    // 使用 shadowing
    let z = 5;
    let z = z + 1;  // 新变量
    let z = z * 2;  // 新变量
    println!("z = {}", z);  // 12
}
▶ Run

遮蔽的用途

rust
fn main() {
    // 1. 类型转换
    let spaces = "   ";
    let spaces = spaces.len();  // &str -> usize

    // 2. 复用变量名
    let numbers = vec![1, 2, 3];
    let numbers = numbers.iter().sum::<i32>();  // Vec -> i32

    // 3. 条件转换
    let input = "42";
    let input: i32 = match input.parse() {
        Ok(num) => num,
        Err(_) => 0,
    };
}
▶ Run

类型推断

自动推断

rust
fn main() {
    // Rust 可以推断类型
    let guess = 42;           // i32
    let pi = 3.14;            // f64
    let greeting = "Hello";   // &str
    let is_rust = true;       // bool
}
▶ Run

需要类型标注的情况

rust
fn main() {
    // 1.  ambiguous 类型
    let num: i32 = "42".parse().unwrap();

    // 2. 默认类型不适用
    let big_num: u128 = 100;

    // 3. 空集合
    let mut vec: Vec<i32> = Vec::new();

    // 4. 函数参数和返回值
    fn add(x: i32, y: i32) -> i32 {
        x + y
    }
}
▶ Run

类型推断规则

┌─────────────────────────────────────────────────────┐
│              类型推断规则                            │
├─────────────────────────────────────────────────────┤
│                                                     │
│  整数默认为 i32                                      │
│  浮点数默认为 f64                                    │
│  布尔默认为 bool                                     │
│  字符串字面量为 &str                                 │
│                                                     │
│  推断流程:                                          │
│  1. 查看初始值                                       │
│  2. 查看使用上下文                                   │
│  3. 如果无法推断,需要显式标注                       │
│                                                     │
└─────────────────────────────────────────────────────┘

小结

  • 变量遮蔽(Shadowing):用同名 let 声明覆盖前一个绑定
  • 遮蔽可以改变变量类型,而 mut 不能改变类型
  • 遮蔽创建了新变量,原变量在其作用域内依然有效
  • 合理使用遮蔽避免冗余命名

练习题

详见:练习题