当返回对范围之外的值的可变引用的不可变引用时,为什么在范围结束时丢弃了可变引用?

时间:2018-07-30 09:55:11

标签: rust mutable dereference borrowing

fn main() {
    // block1: fails
    {
        let mut m = 10;

        let n = {
            let b = &&mut m;
            &**b // just returning b fails
        };

        println!("{:?}", n);
    }

    // block2: passes
    {
        let mut m = 10;

        let n = {
            let b = &&m;
            &**b // just returning b fails here too
        };

        println!("{:?}", n);
    }
}

block1 失败,并显示以下错误:

error[E0597]: borrowed value does not live long enough
  --> src/main.rs:7:22
   |
7  |             let b = &&mut m;
   |                      ^^^^^^ temporary value does not live long enough
8  |             &**b // just returning b fails
9  |         };
   |         - temporary value dropped here while still borrowed
...
12 |     }
   |     - temporary value needs to live until here

我正确的假设是内部不可变引用扩展到 block2 范围之外,而在 block1 中,即使存在外引用吗?

1 个答案:

答案 0 :(得分:6)

在这里,将可变借款视为获取参考值所有权的非Copy结构(在下面的摘要中为S)就足够了。这种模型代表了可变借款的排他性。

基于此模型的原因:在block2中,n是对原始m的引用,而在block1中,n将是对{{1}的副本的引用}由可变借贷拥有。在两个块中,内部引用都在let块的末尾删除,但是仅在块1中,这会引起问题,因为在块1中,m的引用目标仍归内部引用所有参考已删除。

n

struct S { m: i32 } let mut m = 10; let n = { let s = S { m }; let b = &s; &(*b).m }; // s is dropped println!("{:?}", n); 上方的代码段中,拥有s副本的所有权。引用m指向n的副本,该副本在删除n时被删除-不允许。如果s是非副本,则m将被移到m中,这将具有相同的含义。

在块2中,原始s是直接借用的,而不复制它。如果强行复制,将得到与block1相同的错误:

m