错误[E0502]:无法将“向量”借用为不可变的,因为它也被借为可变的

时间:2018-08-20 16:39:15

标签: rust borrow-checker

在函数内部,我试图将一个值推入向量,然后返回对该值的引用,该引用位于向量内。可悲的是,它不起作用,并且出现以下错误:

error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable
  --> src/lib.rs:11:19
   |
10 |     let _unit_0 = push_and_get(&mut vector);
   |                                     ------ mutable borrow occurs here
11 |     let _unit_1 = vector.last().unwrap();
   |                   ^^^^^^ immutable borrow occurs here
12 | }
   | - mutable borrow ends here

这是我的代码,具有两个功能(this_worksthis_does_not_work),据我了解,它们执行相同的操作,但只有其中一个有效。

fn this_works() {
    let mut vector = Vec::new();
    vector.push(());
    let _unit_0 = vector.last().unwrap();
    let _unit_1 = vector.last().unwrap();
}

fn this_does_not_work() {
    let mut vector = Vec::new();
    let _unit_0 = push_and_get(&mut vector);
    let _unit_1 = vector.last().unwrap();
}

fn push_and_get(vector: &mut Vec<()>) -> &() {
    vector.push(());
    vector.last().unwrap()
}

由于Rust的限制,是否有任何方法可以使push_and_get函数正常工作?如果是第一个,我该如何工作?如果是后者,是否有解决此特定问题的计划,或者有什么充分的理由为什么不应该解决此问题?

1 个答案:

答案 0 :(得分:0)

经过更多测试,我想我现在可以回答我自己的问题。提供的示例可以进一步简化以显示核心问题。这是重现该错误所需的实际最小代码量:

// I have embedded the error message as comments
fn main() {
    let mut owned: () = ();
    let ref0: &() = &mut owned;
    //              ---------- mutable borrow occurs here
    let ref1: &() = &owned;
    //              ^^^^^^ immutable borrow occurs here
    drop(ref0);
    //   ---- mutable borrow later used here
}

这归结为,Rust允许将&mut转换为&,但仅在理论上是这样。实际上,只要您使用从可变借贷创建的借用,而又有了另一笔常规借用,编译器就会突然意识到,转换后的借贷仍然是可变借用。类型检查器在说谎。

最后,不可能将push()和last()组合成一个函数。

P.S。如果Rust支持将来从&mut&的真实转换,那会很好,将来不会产生上述错误。