为什么这个Rust程序忽略了不变性

Vir*_*raj 7 rust

我有以下Rust程序,我希望它会导致编译错误,因为x稍后会重新分配.但它符合并提供输出.为什么?

fn main() {
   let (x, y) = (1, 3);
   println!("X is {} and Y is {}", x, y);

   let x: i32 = 565;
   println!("Now X is {}", x);
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*lec 13

Rust实际上允许您对块中的其他变量进行阴影处理,因此let x: i32 = 565;定义了一个新的变量x,该变量使用x前面定义的阴影let (x,y) = (1,3);.请注意,您甚至可以重新定义x为具有不同的类型,因为第二个x是一个全新的变量!

fn main(){
   let x = 1;
   println!("Now X is {}",x);

   let x = "hi";
   println!("Now X is {}",x);
}
Run Code Online (Sandbox Code Playgroud)

这个reddit线程详细介绍了这个有用的原因.提到的两件看起来很有趣的事情是:

  • 对于获取变量所有权但返回相同类型的另一个变量的操作,有时"看起来很好"将重新定义的返回变量具有相同的名称.从这里:

    let iter = vec.into_iter();
    let iter = modify(iter);
    let iter = double(iter);
    
    Run Code Online (Sandbox Code Playgroud)
  • 或者使变量不可变:

    let mut x;
    // Code where `x` is mutable
    let x = x;
    // Code where `x` is immutable
    
    Run Code Online (Sandbox Code Playgroud)

  • 当我有中间类型时,我使用阴影,并将其转换为其他内容,因为我知道我不再需要它.例如,一个函数有一个参数`foo:Option <u32>`,我立即用`let foo = foo.unwrap_or(0)`打开它.这节省了我不得不考虑这个变量的新名称,并防止未来的维护者必须考虑使用哪个看起来相似的变量. (7认同)
  • @Dai我认为你不能......你总是可以将所有权转让给另一个变量`let y = x`. (3认同)
  • @Viraj:这是允许的,因为它被认为是有用的.大多数语言都允许在一定程度上进行阴影处理,尽管Rust可能是唯一的,因为它允许在同一个块中进行阴影处理.至于逻辑错误......它摆动两种方式.有时能够保证以后不访问参数/变量也是非常有用的.老实说,虽然我不想使用它. (3认同)