当变量在 Rust 中移动时,它会在引擎盖下进行变量阴影吗?
When variables move in rust does it do variable shadowing under the hood?
我想知道当变量从一个作用域移动到另一个作用域时,rust 是否在幕后进行变量遮蔽。
因为当我将变量移动到另一个函数时,可以更改另一个函数的签名以使变量可变,但是当变量 moved/returned 从其他函数返回到 main 时,它不再是不可变的。
我只是对这里发生的事情感到好奇。
fn main() {
let vec0 = Vec::new(); // immutable by default
let mut vec1 = foreign_func(vec0); // vec0 has now moved
// Is foreign_func returning a mutable vector? Because without `mut` keyword vec1 is immutable by default.
vec1.push(10);
}
fn foreign_func(mut vec: Vec<i32>) -> Vec<i32> {
// argument passed for vec is now mutable in this scope.
// Is this like variable shadowing?
// let test = 10;
// let mut test = 20;
vec.push(20);
vec
}
没有不可变的Vec
,只有变量或借用可以不可变(实际上unique/exclusive,但在Vec
的情况下是一样的).
在您的示例中发生的是 移动 :Vec
首先从 main
的 vec0
移动到 foreign_func
的vec
,然后回到main
,这次是vec1
。其中一些绑定是 mut
而另一些不是,但这与移动的值无关。事实上,将 Vec
从不可变变量转换为可变变量可以像 let mut vec1 = vec0
一样简单,它编译得很好。
正如 Peter Hall 所指出的,阴影是一个不同的概念:引入一个有意共享现有变量名称的新变量。由于这两个变量具有相同的名称,因此在其范围内只能访问最近的一个。请注意,被隐藏的变量和隐藏它的变量不必具有相同的类型,并且在隐藏时可能会或可能不会发生移动:
fn shadow1(v: Option<Vec<u32>>) {
// here shadowing moves the old value
let v = v.unwrap_or_else(Vec::new);
}
fn shadow2(v: Vec<u32>) {
// here shadowing not accompanied by move
let v = v.as_slice();
}
当没有移动时,阴影值有可能在操作结束后再次有用。在那种情况下,可以在单独的作用域中引入阴影变量,以便在内部作用域完成后旧值重新出现:
fn shadow3(v: Vec<u32>) {
{
let v = v.as_slice();
// temporarily working with a &[u32] slice, Vec is inaccessible
}
// here we have the Vec again
}
我想知道当变量从一个作用域移动到另一个作用域时,rust 是否在幕后进行变量遮蔽。
因为当我将变量移动到另一个函数时,可以更改另一个函数的签名以使变量可变,但是当变量 moved/returned 从其他函数返回到 main 时,它不再是不可变的。
我只是对这里发生的事情感到好奇。
fn main() {
let vec0 = Vec::new(); // immutable by default
let mut vec1 = foreign_func(vec0); // vec0 has now moved
// Is foreign_func returning a mutable vector? Because without `mut` keyword vec1 is immutable by default.
vec1.push(10);
}
fn foreign_func(mut vec: Vec<i32>) -> Vec<i32> {
// argument passed for vec is now mutable in this scope.
// Is this like variable shadowing?
// let test = 10;
// let mut test = 20;
vec.push(20);
vec
}
没有不可变的Vec
,只有变量或借用可以不可变(实际上unique/exclusive,但在Vec
的情况下是一样的).
在您的示例中发生的是 移动 :Vec
首先从 main
的 vec0
移动到 foreign_func
的vec
,然后回到main
,这次是vec1
。其中一些绑定是 mut
而另一些不是,但这与移动的值无关。事实上,将 Vec
从不可变变量转换为可变变量可以像 let mut vec1 = vec0
一样简单,它编译得很好。
正如 Peter Hall 所指出的,阴影是一个不同的概念:引入一个有意共享现有变量名称的新变量。由于这两个变量具有相同的名称,因此在其范围内只能访问最近的一个。请注意,被隐藏的变量和隐藏它的变量不必具有相同的类型,并且在隐藏时可能会或可能不会发生移动:
fn shadow1(v: Option<Vec<u32>>) {
// here shadowing moves the old value
let v = v.unwrap_or_else(Vec::new);
}
fn shadow2(v: Vec<u32>) {
// here shadowing not accompanied by move
let v = v.as_slice();
}
当没有移动时,阴影值有可能在操作结束后再次有用。在那种情况下,可以在单独的作用域中引入阴影变量,以便在内部作用域完成后旧值重新出现:
fn shadow3(v: Vec<u32>) {
{
let v = v.as_slice();
// temporarily working with a &[u32] slice, Vec is inaccessible
}
// here we have the Vec again
}