变量绑定

变量绑定

使用 let 声明一个变量(声明一个变量相当于告诉 Rust 创建一个变量)。

fn main() {
    let my_number = 8;
    println!("Hello, number {}", my_number);
}

代码块

变量在代码块 {} 中开始和结束。在此示例中,my_number 在我们调用 println!之前结束,因为它在其自己的代码块内。

fn main() {
    {
        let my_number = 8; // my_number starts here
                           // my_number ends here!
    }

    println!("Hello, number {}", my_number); // ⚠️ there is no my_number and
                                             // println!() can't find it
}

您可以使用代码块返回值:

fn main() {
    let my_number = {
        let second_number = 8;
            second_number + 9 // No semicolon, so the code block returns 8 + 9.
                            // It works just like a function
    };

    println!("My number is: {}", my_number);
}

如果在块内添加分号,它将返回 ()(无):

fn main() {
    let my_number = {
        let second_number = 8; // declare second_number,
            second_number + 9; // add 9 to second_number
                            // but we didn't return it!
                            // second_number dies now
    };

    println!("My number is: {:?}", my_number); // my_number is ()
}

可变性

使用 let 声明变量时,该变量是不可变的(无法更改)。这将不起作用:

fn main() {
    let my_number = 8;
    my_number = 10; // error[E0384]: cannot assign twice to immutable variable my_number.
}

要更改变量,请添加 mut:

fn main() {
    let mut my_number = 8;
    my_number = 10;
}

但是,即使使用 mut 也不能更改类型。这将不起作用:

fn main() {
    let mut my_variable = 8;
    my_variable = "Hello, world!"; // expected integer, found &str
}

Shadowing

阴影意味着使用 let 声明一个与另一个变量同名的新变量。它看起来像可变性,但完全不同。阴影看起来像这样:

fn main() {
    let my_number = 8; // This is an i32
    println!("{}", my_number); // prints 8
    let my_number = 9.2; // This is an f64. It is not my_number - it is completely different!
    println!("{}", my_number) // Prints 9.2
}

在这里,我们说我们用新的绑定遮盖了 my_number。那么第一个 my_number 是否已销毁?不,但是当我们调用 my_number 时,我们现在得到 my_number f64。并且由于它们在同一个作用域块中,因此我们无法再看到第一个 my_number。但是,如果它们位于不同的块中,则可以同时看到两者。例如:

fn main() {
    let my_number = 8; // This is an i32
    println!("{}", my_number); // prints 8
    {
        let my_number = 9.2; // This is an f64. It is not my_number - it is completely different!
        println!("{}", my_number) // Prints 9.2
                                  // But the shadowed my_number only lives until here.
                                  // The first my_number is still alive!
    }
    println!("{}", my_number); // prints 8
}

那么阴影的好处是什么?需要大量更改变量时,阴影效果很好。

fn main() {
    let final_number = {
        let y = 10;
        let x = 9; // x starts at 9
        let x = times_two(x); // shadow with new x: 18
        let x = x + y; // shadow with new x: 28
        x // return x: final_number is now the value of x
    };
    println!("The number is now: {}", final_number)
}

fn times_two(number: i32) -> i32 {
    number * 2
}

没有阴影,即使您不在乎 x,您也必须考虑不同的名称:

fn main() {
    // Pretending we are using Rust without shadowing
    let final_number = {
        let y = 10;
        let x = 9; // x starts at 9
        let x_twice = times_two(x); // second name for x
        let x_twice_and_y = x_twice + y; // third name for x
        x_twice_and_y // too bad we didn't have shadowing - we could have just used x
    };
    println!("The number is now: {}", final_number)
}

fn times_two(number: i32) -> i32 {
    number * 2
}

无值变量

没有值的变量称为“未初始化”变量。未初始化表示“尚未开始”。它们很简单,只需命名为:

fn main() {
    let my_variable; // ⚠️
}

但是您还不能使用它。您的程序如果尝试使用将无法编译。但是有时候它们会有用。一个好例子是:在以下情况中:您有一个代码块,并且在内部是变量的值,并且该变量需要位于代码块之外。

fn loop_then_return(mut counter: i32) -> i32 {
    loop {
        counter += 1;
        if counter % 50 == 0 {
            break;
        }
    }
    counter
}

fn main() {
    let my_number;

    {
        // Pretend we need to have this code block
        let number = {
            // Pretend there is code here to make a number
            7
        };

        my_number = loop_then_return(number);
    }

    println!("{}", my_number);
}

重要的是要知道 my_number 是在 main() 函数中声明的,因此它一直存在到最后。但是它从循环内部获得其价值。但是,该值与 my_number 一样长,因为 my_number 具有该值。它有助于想象是否简化了代码。loop_then_return(number)给出结果 50,所以我们将其删除并写 50。另外,现在我们不需要数字,因此我们也将其删除。现在看起来像这样:

fn main() {
    let my_number;
    {
        my_number = 50;
    }

    println!("{}", my_number);
}
下一页