Search code examples
rustimmutabilitydestructuring

Immutable variables in RUST can be reassigned using destructuring?


I was quite surprised to find that the following program will happily compile and run (using "cargo 1.42.0 (86334295e 2020-01-31)."), outputting:

5 k

The variable x which is not declared as mut is not only reassigned but reassigned with a different type. Is there some reason why you are allowed to do this?

fn main() {

    let x = 5;

    println!("{}", x);

    let t: (i32, f64, char) = (2, 3.14, 'k');

    let (_,_,x) = t;

    println!("{}", x);

}

Solution

  • This is called "shadowing a variable"

    (https://doc.rust-lang.org/book/ch03-01-variables-and-mutability.html#shadowing)

    It can also been shown as simply as so:

    let x = 5;
    let x = 'k';
    

    It actually comes in handy often. For instance, you can reuse an identifier after you are done using its initially assigned value:

    let two_times_five = 2 * 5; // type i32
    let two_times_five = two_times_five.to_string(); // type String
    

    The compiler will still enforce strong typing; accesses to two_times_five before its redefinition will be accessing an i32, accesses afterward will be accessing a String.

    There are also times when you don't want a variable to be mutable, but at some point you want to assign it a different value. Using variable shadowing rather than let mut means you know the variable is not changed in between its definitions, regardless of what functions it's passed into or methods are called on it.