binding - let-rebinding 和标准赋值有什么区别?

标签 binding scope rust

在 Rust 中,为了改变可变变量的值,以下示例代码中的 let x = 12x = 12 有什么区别?

fn main() {
    let mut x: i32 = 8;
    {
        println!("{}", x); 
        let x = 12;  // what if change to x = 12
        println!("{}", x); 
    }
    println!("{}", x); 
    let x =  42;
    println!("{}", x); 
}

输出为 8, 12, 8, 42。如果我将 let x = 12 更改为 x = 12 ...

fn main() {
    let mut x: i32 = 8;
    {
        println!("{}", x); 
        x = 12; 
        println!("{}", x); 
    }
    println!("{}", x); 
    let x =  42;
    println!("{}", x); 
}

输出为 8, 12, 12, 42

我理解 Rust 使用 let 来做变量绑定(bind),所以 let x = 12 是一个变量重新绑定(bind),绑定(bind)只在一个范围内有效。但是如何解释x = 12的功能和对应的作用域呢?那是一种变量绑定(bind)吗?

最佳答案

第二个 let x 引入了第二个绑定(bind),隐藏 block 其余部分的第一个绑定(bind)。也就是说,有两个名为 x 的变量,但您只能在 let x = 12; 语句之后的 block 语句中访问第二个变量。这两个变量不需要具有相同的类型!

然后,在 block 语句之后,第二个 x 超出范围,因此您再次访问第一个 x

但是,如果您改写 x = 12;,那将是一个赋值表达式:x 中的值将被覆盖。这不会引入新变量,因此赋值的类型必须与变量的类型兼容。

如果您编写循环,这种差异很重要。例如,考虑这个函数:

fn fibonacci(mut n: u32) -> u64 {
    if n == 0 {
        return 1;
    }

    let mut a = 1;
    let mut b = 1;

    loop {
        if n == 1 {
            return b;
        }

        let next = a + b;
        a = b;
        b = next;
        n -= 1;
    }
}

此函数重新分配变量,以便循环的每次迭代都可以对前一次迭代分配的值进行操作。

但是,您可能会想像这样编写循环:

loop {
    if n == 1 {
        return b;
    }

    let (a, b) = (b, a + b);
    n -= 1;
}

这行不通,因为 let 语句引入了新的变量,而这些变量会在下一次迭代开始之前超出作用域。在下一次迭代中,(b, a + b) 仍将使用原始值。

关于binding - let-rebinding 和标准赋值有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40323500/

相关文章:

WPF:用于显示数据的网格的替代方案?

javascript - 变量在 for 循环中变为未定义

while-loop - 是否可以在 `while let` 中使用模式匹配守卫?

javascript - React.js 中的 Spread Notation 渲染函数和变量作用域

jsf-2 - 在新浏览器选项卡中重新打开页面时如何重置 session 作用域 bean

c++ - 从C++调用Rust时,如何通过引用传递参数?

arrays - 如何将可变数组划分为可变子数组

WPF DataGrid ItemsSource 绑定(bind)问题

forms - 使用绑定(bind)解析数组表单元素

xaml - 将 ScrollViewer 从 ViewModel 绑定(bind)到 View