Rust 变量作用域

在计算机编程中,变量的作用域定义了变量可用的区域。例如,

fn main() {
    // this variable has scope inside the main function block
    let age = 31;
    …
}

在这里,age 变量的作用域在 main() 函数的主体 {...} 内,

注意: Rust 中的每个变量都具有在块内有效的作用域。块是由花括号 {} 包围的语句集合。


Rust 中变量作用域的工作原理

让我们通过一个示例来了解变量作用域是如何工作的,

fn main() {
    // scope of outer_var variable is inside the main function code block
    let outer_var = 100;
    
    // start of the inner code block
    {
        // scope of inner_var variable is only inside this new code block
        let inner_var = 200;
        println!("inner_var = {}", inner_var);
    }
    // end of the inner code block
    
println!("inner_var = {}", inner_var);
println!("outer_var = {}", outer_var); }

在这里,如果我们尝试在内部代码块之外打印 inner_var,程序将无法编译,并出现错误。

输出

error[E0425]: cannot find value `inner_var` in this scope
  --> src/main.rs:13:32
   |
13 |     println!("inner_var = {}", inner_var);
   |                                ^^^^^^^^^ help: a local variable with a similar name exists: `outer_var`

Rust 编译器在内部代码块之外尝试打印变量时找不到作用域内的 inner_var

要解决此问题,我们可以这样做:

fn main() {
    // scope of outer_var variable is inside the main function code block
    let outer_var = 100;
    
    // start of the inner code block
    {
        // scope of inner_var variable is only inside this new code block
        let inner_var = 200;
        println!("inner_var = {}", inner_var);
        println!("outer_var inside inner block = {}", outer_var);
    }
    // end of the inner code block
    
    println!("outer_var = {}", outer_var);
}

输出

inner_var = 200
outer_var inside inner block = 100
outer_var = 100

我们从外部代码块中移除了 println!("inner_var = {}", inner_var);,程序现在可以按预期工作。

此外,我们可以在内部代码块中访问 outer_var,因为它的作用域在 main() 函数中。

Rust 中变量作用域的工作方式如下:

Working of variable scope in Rust
Rust 中变量作用域的工作原理

Rust 中的变量遮蔽

在 Rust 中,当一个在特定作用域内声明的变量与在外部作用域内声明的变量同名时,这被称为变量遮蔽

我们可以在同一程序的不同作用域块中使用相同的变量名。

让我们看一个例子:

fn main() {
    let random = 100;

    // start of the inner block
    {
        println!("random variable before shadowing in inner block = {}", random);

        // this declaration shadows the outer random variable
        let random = "abc";

        println!("random after shadowing in inner block = {}", random);
    }
    // end of the inner block

    println!("random variable in outer block = {}", random);
}

输出

random variable before shadowing in inner block = 100
random after shadowing in inner block = abc
random variable in outer block = 100

在这里,外部块中声明的 random 变量在内部块中被遮蔽了。让我们看看这意味着什么,

let random = "abc";

内部块中的 random 变量值将遮蔽外部块的值,因此内部块将具有 "abc" 的值。但是,内部块之外的 random 变量的值保持不变。


Rust 中的变量冻结

我们可以使用遮蔽和不可变性来冻结 Rust 中的变量。一旦变量被冻结,我们就无法在内部作用域中更改变量的值。

让我们看一个例子。

fn main() {
    let mut age = 1;

    // start of the inner block
    {
        // shadowing by immutable age variable
        let age = age;

        // error, age variable is frozen in this scope
        age = 2;

        println!("age variable inner block = {}", age);
        // age variable goes out of scope
    }
    // end of the inner block

    // age variable is not frozen in outer block
    age = 3;

    println!("integer variable outer block = {}", age);
}

输出

error[E0384]: cannot assign twice to immutable variable `age`
  --> src/main.rs:10:9
   |
7  |         let age = age;
   |             ---
   |             |
   |             first assignment to `age`
   |             help: consider making this binding mutable: `mut age`
...
10 |         age = 31;
   |         ^^^^^^^^ cannot assign twice to immutable variable

在上面的示例中,我们将外部块的可变变量 age 赋值给内部作用域中的同一个不可变变量。

fn main() {
    let mut age = 100;

    {
let age = age;
… } … }

通过这样做,我们用一个名为 age 的不可变变量遮蔽了可变变量 age

现在,age 变量在内部块中被冻结,因为内部 age 变量指向的值与外部块中的 age 变量指向的值相同。

因此,我们无法在内部块中更改 age 的值,并会遇到错误。

一旦我们退出内部块,age 的值就可以更改。

让我们看看变量冻结示例的工作版本。

fn main() {
    let mut age = 100;

    {
        // shadowing by immutable age variable
        let age = age;

        println!("age variable inner block = {}", age);
        // age goes out of scope
    }

    // age variable is not frozen in this scope
    age = 3;

    println!("age variable outer block = {}", age);
}

输出

age variable inner block = 100
age variable outer block = 3

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战