首页 > 解决方案 > 使用现有可变引用的嵌套方法调用

问题描述

以下代码编译成功:

let mut v = vec![1];
let r = &mut v;
r.push(r.len());

而这个失败:

let mut v = vec![1];
let r = &mut v;
r.push(v.len());

有错误:

error[E0502]: cannot borrow `v` as immutable because it is also borrowed as mutable
    |
    |     let r = &mut v;
    |             ------ mutable borrow occurs here
    |     r.push(v.len());
    |            ^ immutable borrow occurs here
    |     r.push(r.len());
    |     - mutable borrow later used here

我怀疑在第一个示例中没有错误,因为编译器没有创建中间引用并且它使用相同的引用:r因此没有多次借用。但是,如果是这样的话,为什么下面的代码无法编译

let mut v = vec![1];
let r = &mut v;
r.push({r.push(0);1});

标签: rustreferenceborrow-checkerborrowing

解决方案


第一个例子:

let mut v = vec![1];
let r = &mut v;
r.push(r.len());

如果没有 2 阶段借用,代码将无法编译,因为外部调用创建了r:的重借&mut *r,而内部调用创建了具有相同值的新的不可变重借:&*r

使用 2 阶段借用,第一个重借将转换为&mut2 *r并稍后在第二个重借超出范围时激活。

第二个例子:

let mut v = vec![1];
let r = &mut v;
r.push(v.len());

即使使用 2-phase 借用,它也无法编译。

内部调用导致v:与 .&mut v冲突的重借r

第三个例子:

let mut v = vec![1];
let r = &mut v;
r.push({r.push(0);0});

即使使用 2-phase 借用,它也无法编译。

内部调用需要2 阶段&mut2借用*r不允许的重借,因为外部调用已经创建&mut2*r.

参考资料


推荐阅读