What is the difference between a let-rebinding and a standard assignment?

狂风中的少年 提交于 2019-12-18 07:00:25

问题


In Rust, in order to change the value of a mutable variable, what is the difference in let x = 12 or x = 12 in the following sample code?

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); 
}

The output is 8, 12, 8, 42. If I change let x = 12 to x = 12 ...

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

The output is 8, 12, 12, 42.

I understand that Rust uses let to do variable binding, so the let x = 12 is a variable rebinding and the binding is only valid inside a scope. But how to explain the functionality of x = 12 and the corresponding scope? Is that a type of variable binding?


回答1:


The second let x introduces a second binding that shadows the first one for the rest of the block. That is, there are two variables named x, but you can only access the second one with the block statement after the let x = 12; statement. These two variables don't need to have the same type!

Then, after the block statement, the second x is out of scope, so you access the first x again.

However, if you write x = 12; instead, that's an assignment expression: the value in x is overwritten. This doesn't introduce a new variable, so the type of the value being assigned must be compatible with the variable's type.

This difference is important if you write a loop. For example, consider this function:

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;
    }
}

This function reassigns variables, so that each iteration of the loop can operate on the values assigned on the preceding iteration.

However, you might be tempted to write the loop like this:

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

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

This doesn't work, because the let statement introduces new variables, and these variables will go out of scope before the next iteration begins. On the next iteration, (b, a + b) will still use the original values.



来源:https://stackoverflow.com/questions/40323500/what-is-the-difference-between-a-let-rebinding-and-a-standard-assignment

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!