Rust 当我可以有可变变量绑定时,为什么我需要重新绑定/隐藏?

Rust 当我可以有可变变量绑定时,为什么我需要重新绑定/隐藏?,rust,Rust,当我可以有可变变量绑定时,为什么我需要重新绑定/隐藏?考虑: let x = a(); let x = b(x); vs 可变变量绑定允许在此基础上可变借用该变量。 但是阴影是否比可变绑定有一些优势呢?我自己找到了一个答案:阴影可以改变变量类型 let x = get_some_string(); let x = x.smart_parse_int(); 因为两者的效果完全不同。 要真正理解发生了什么,我们需要从头开始:什么是绑定?绑定是什么意思 让我们考虑一个简单的函数: fn Helo

当我可以有可变变量绑定时,为什么我需要重新绑定/隐藏?考虑:

let x = a();
let x = b(x);
vs

可变变量绑定允许在此基础上可变借用该变量。
但是阴影是否比可变绑定有一些优势呢?

我自己找到了一个答案:阴影可以改变变量类型

let x = get_some_string();
let x = x.smart_parse_int();

因为两者的效果完全不同。


要真正理解发生了什么,我们需要从头开始:什么是绑定?绑定是什么意思

让我们考虑一个简单的函数:<代码> fn HeloLoE()>字符串;<代码>

这样调用此函数时:

fn main() {
    hello();
}
会发生什么

该函数返回一个
字符串
,该字符串立即被丢弃(执行
Drop
,从而释放内存)

结果被删除是因为它没有绑定到变量名,语言规则说,如果没有绑定,那么它可以立即被删除1

然而,如果我们绑定这个结果,我们就延长了这个值的寿命,并且我们可以通过这个绑定来访问它。。。有一段时间

fn main() {
    let value = hello();

    std::mem::drop(value);

    println!("{}", value); // Error: moved out of value
}
这是当前的问题:在Rust中,值的生存期与绑定范围无关

在绑定退出其作用域之前,甚至不需要删除值:它可以被传输到另一个(类似于从函数返回)

1如果绑定到
\uu
,也会发生同样的情况


因此,现在我们了解了绑定和值不同的事实,让我们来检查这两个片段

第一个阴影片段,与您的不同:

fn main() {
    let x = a();
    let x = b();
}
步骤,按顺序:

  • 表达式
    a()
    创建一个值,该值绑定到
    x
  • 表达式
    b()
    创建一个值,该值绑定到
    x
  • b()
    创建的值将被删除
  • a()
    创建的值将被删除
请注意,
x
被重新绑定的事实并不影响先前绑定的值的生存期

从技术上讲,它的行为就像
b()
的结果被绑定到
y
,唯一的例外是
x
绑定在
y
范围内时无法访问

现在,可变片段:

fn main() {
    let mut x = a();
    x = b();
}
步骤,按顺序:

  • 表达式
    a()
    创建一个值,该值绑定到
    x
  • 表达式
    b()
    创建一个值,该值绑定到
    x
    ,并删除上一个值(由
    a()
    创建)
  • b()
    创建的值将被删除

再一次,访问上一个值是不可能的,但是使用阴影暂时是不可能的(如果阴影在较小的范围内),使用赋值是永远不可能的,因为该值被删除。

不仅如此。您还可以更改可变性(这是常见的用例):
让mut-foo=foo::new();/*构建foo*/let foo=foo;//使foo不可变
@ukaszNiemier:注意,您可以简单地使用块表达式,
让foo={let mut foo=foo::new();…;foo}一个奇妙的答案,使灯泡终于打开了。不应
x=yfn main(){let x;{let y=hello();x=y;}println!(“{}”,x);}
be
let x=y另外,你能向像我这样的新手解释为什么“b”创造的价值比“a”创造的价值先被删除吗。努力确保我完全吸收这些。@Kayote:(1)不,我的意思是
x=y<代码>让x
是一种预先声明绑定而不实际绑定的方法。此处使用此选项将值分配给
y
以避开其范围。(2) 在词法范围的末尾,变量按与其创建相反的顺序被销毁;这是必要的,这样一个变量就可以引用它之前声明的变量。例如,考虑<代码>让VEC= VEC!(1, 2); 设x=&vec[0]:如果先销毁
vec
x
将指向释放的内存!这是否意味着阴影可能导致某种内存泄漏?在代码段
fn main(){let x=a();let x=b();}
中,由
a()
创建的值可能会一直持续到过程结束,而没有其他地方使用它。可能只有我,但这个答案显示了两者的不同之处以及它们的工作方式;我不太明白为什么这个特性一开始就内置在语言中,特别是当你可以很容易地说
let x=a();设y=b()
而不是使用阴影将
x
重新绑定两次。@code\u dredd:这个答案假设使用相同的名称是可取的,因为在OP中重复使用相同的名称。阴影是否是可取的,而不仅仅是使用不同的名称,这是所有语言设计者必须考虑的一个独立问题;虽然我不确定它在StackOverflow上是如何接收的,但这确实是一个令我感兴趣的问题。
fn main() {
    let x = a();
    let x = b();
}
fn main() {
    let mut x = a();
    x = b();
}