在Rust中以相同的变量名称多次使用let关键字

Jos*_*ein 1 move rust

生锈的新手,我已经过了借阅检查器卡住的阶段,但是我对这段代码为什么起作用或通过感到困惑。我正在实现一个类似于结构的枚举,该枚举充当某种形式的节点,可以附加到以下节点:

#[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)}
       }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于main明显的原因,以下函数无法正常工作,您无法将其分配给不可变变量:

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

但是,如果我let再次与foo一起使用,则代码可以正常运行!

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 } } 
Run Code Online (Sandbox Code Playgroud)

我的问题是,为什么编译器允许let同一变量多次使用?如果是故意的,那甚至意味着或表示什么?是在幕后创建了一个名为foo的新变量并删除了旧变量吗?

Pet*_*aro 5

这称为可变阴影。第二个foo绑定的值与第一个绑定的值不同,而是一个全新的值。有关更多详细信息,请参阅《锈书》的“ 阴影”一章,即:

[...]您可以声明一个与前一个变量同名的新变量,并且新变量会覆盖前一个变量。Rustaceans说,第一个变量被第二个变量遮盖,这意味着第二个变量的值就是使用该变量时出现的值。