当我可以有可变变量绑定时,为什么我需要重新绑定/阴影?考虑:
let x = a();
let x = b(x);
与
let mut x = a();
x = b(x);
可变变量绑定允许在this上可变地借用该变量。但是,与可变绑定相比,隐藏是否有一些优势呢?
因为两者的效果完全不同。
要真正理解发生了什么,我们需要从头开始:什么是绑定?绑定是什么意思?
我们考虑一个简单的函数:fn hello() -> String;
.
当像这样调用这个函数时:
fn main() {
hello();
}
会发生什么?
函数返回一个String
,它被立即丢弃(执行Drop
,因为它释放了它的内存)。
结果被删除,因为它没有绑定到变量名,并且语言规则说,如果没有绑定,则可以立即删除1。
如果我们绑定这个结果,然而,我们延长了这个值的生命周期,我们可以通过这个绑定访问它…一段时间。
fn main() {
let value = hello();
std::mem::drop(value);
println!("{}", value); // Error: moved out of value
}
这个就是问题所在:在Rust中,值的生命周期与绑定的作用域无关。
一个值甚至不需要在它的绑定退出它的作用域之前被删除:它可以被转移到另一个值(类似于从函数返回)。
fn main() {
let x;
{
let y = hello();
x = y;
}
println!("{}", x);
}
1与_
绑定时发生相同的情况。
那么,现在我们知道绑定和值是不同的,让我们来检查一下这两个代码片段。
第一个影子片段,与你的不同:
fn main() {
let x = a();
let x = b();
}
步骤,按顺序:
- 表达式
a()
创建一个值,该值绑定到x
- 表达式
b()
创建一个值,该值绑定到x
- 删除
b()
创建的值 - 删除
a()
创建的值
请注意,重新绑定x
并不影响先前绑定的值的生命周期。
从技术上讲,它的行为就像b()
的结果被绑定到y
一样,唯一的例外是,当y
在作用域中时,之前的x
绑定是不可访问的。
fn main() {
let mut x = a();
x = b();
}
步骤,按顺序:
- 表达式
a()
创建一个值,该值绑定到x
- 表达式
b()
创建一个值,该值绑定到x
,并且删除之前由a()
创建的值 - 删除
b()
创建的值
再一次,访问前一个值是不可能的,然而,使用遮蔽是暂时不可能的(如果在较小的范围内遮蔽),使用赋值是永远不可能的,因为值被删除了。
我自己找到了一个答案:影子可以改变变量的类型。
let x = get_some_string();
let x = x.smart_parse_int();