当我可以进行可变变量绑定时,为什么还需要重新绑定/阴影?

时间:2016-11-15 23:07:29

标签: rust

为什么我可以进行可变变量绑定时需要重新绑定/阴影?考虑:

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

VS

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

可变变量绑定允许对此变量进行可变借用。 但阴影是否比可变绑定有一些优势?

2 个答案:

答案 0 :(得分:13)

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

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

让我们考虑一个简单的函数: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绑定一样,唯一的例外是xy之前无法访问的fn main() { let mut x = a(); x = b(); } 绑定在范围内。

现在,可变片段:

a()

步骤,按顺序:

  • 表达式x创建一个绑定到b()
  • 的值
  • 表达式x创建一个绑定到a()的值,并删除之前的值(由b()创建)
  • $last_insert_id = DB::table('information_schema.tables') ->where('table_name', $table_name) ->whereRaw('table_schema = DATABASE()') ->select('AUTO_INCREMENT')->first(); 创建的值已被删除

再一次,访问前一个值是不可能的,但是在使用阴影的情况下暂时不可能(如果在较小的范围内进行阴影处理),由于值被删除,因此无法永久地进行分配。

答案 1 :(得分:9)

我发现自己的一个答案:阴影可以改变变量类型。

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