Search code examples
rustmove

Using let keyword multiple times with same variable name in rust


New to rust, I am passed the phase where I get stuck with the borrow checker, but I am stuck with why this piece of code works or passes. I am implementing an struct-like enum that acts as some form of a node that can be appended to:

#[derive(Debug)]
enum Node {
    Val {num:u32, next:Box<Node>},
    Nil
}

impl Node {
    fn put_next(&self, i:u32) -> Node {
       match self {
           Node::Val {num, next:_} => Node::Val {num:*num, next:Box::new(Node::Val {num:i, next:Box::new(Node::Nil)})},
           Node::Nil => Node::Val {num:i, next:Box::new(Node::Nil)}
       }
    }
}

The following main function does not work for obvious reasons, you can't assign to an immutable variable:

fn main() {
   let foo = Node::Val {num:5, next:Box::new(Node::Nil)};
   foo = foo.put_next(30);
   println!("foo {:?} ", foo);
}

However, if I use let with foo again, the code works with no errors!

fn main() {
   let foo = Node::Val {num:5, next:Box::new(Node::Nil)};
   let foo = foo.put_next(30);
   println!("foo {:?} ", foo);
}
// foo Val { num: 5, next: Val { num: 30, next: Nil } } 

My question here is, why does the compiler allow let to be used multiple times with the same variable? If it's intentional, what does that even mean or indicate? Is it, under the hood creating a new variable named foo and dropping the old one?


Solution

  • This is called variable shadowing. The second foo is not bound to the same value as the first one but a completely new one. For more details look into the Shadowing chapter of The Rust Book, that is:

    [...] you can declare a new variable with the same name as a previous variable, and the new variable shadows the previous variable. Rustaceans say that the first variable is shadowed by the second, which means that the second variable’s value is what appears when the variable is used.