简体   繁体   English

当变量在 rust 中移动时,它是否会在引擎盖下进行变量遮蔽?

[英]When variables move in rust does it do variable shadowing under the hood?

I wanted to know if rust is doing variable shadowing under the hood when variables move from one scope to another.我想知道当变量从一个 scope 移动到另一个时,rust 是否正在做变量遮蔽。

Since when I move a variable to another function the other function's signature can be changed to make the variable mutable and but when the variable is moved/returned back from other function to main it's not immutable anymore.因为当我将变量移动到另一个 function 时,可以更改另一个函数的签名以使变量可变,但是当变量从其他 function 移动/返回到 main 时,它不再是不可变的。

I am just curious to what's happening here.我只是好奇这里发生了什么。

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
}

There's no such thing as an immutable Vec , it's only a variable or a borrow that can be immutable (actually unique/exclusive, but in case of Vec that's the same thing).没有不可变的Vec这样的东西,它只是一个可以不可变的变量或借用(实际上是唯一的/排他的,但在Vec的情况下,这是同一件事)。

What happens in your example is a move : the Vec first moves from main 's vec0 into foreign_func 's vec , and then back to main , this time to vec1 .在您的示例中发生的是一个移动Vec首先从mainvec0移动到foreign_funcvec ,然后回到main ,这次是vec1 Some of these bindings are mut and some are not, but that has no bearing on the moved value.其中一些绑定是mut ,而另一些则不是,但这与移动的值无关。 In fact, transferring a Vec from an immutable to a mutable variable can be as simple as let mut vec1 = vec0 , which compiles just fine.事实上,将Vec从不可变变量转移到可变变量可以像let mut vec1 = vec0一样简单,编译得很好。

As pointed out by Peter Hall, shadowing is a different concept: introducing a new variable which intentionally shares the name of an existing one.正如 Peter Hall 所指出的,阴影是一个不同的概念:引入一个有意共享现有变量名称的新变量。 Since the two variables have the same name, only the most recent one is accessible in its scope.由于这两个变量具有相同的名称,因此在其 scope 中只能访问最近的一个。 Note that the shadowed variable and the one that shadowed it don't have to have the same type, and that a move may or may not occur when shadowing:请注意,被遮蔽的变量和遮蔽它的变量不必具有相同的类型,并且在遮蔽时可能会或可能不会发生移动:

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();
}

When there is no move, it is possible that the shadowed value will again become useful after an operation ends.当没有移动时,阴影值可能会在操作结束后再次变得有用。 In that case the shadowing variable may be introduced in a separate scope, so that the old value resurfaces after the inner scope finishes:在这种情况下,可以在单独的 scope 中引入阴影变量,以便在内部 scope 完成后旧值重新出现:

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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM