【问题标题】:error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable错误[E0502]:不能将`vector`借用为不可变的,因为它也被借用为可变的
【发布时间】:2018-08-20 16:39:14
【问题描述】:

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

error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable
  --> src\lib.rs:19:19
   |
18 |     let _unit_0 = push_and_get(&mut vector);
   |                                ----------- mutable borrow occurs here
19 |     let _unit_1 = vector.last().unwrap();
   |                   ^^^^^^ immutable borrow occurs here
20 |     drop(_unit_0);
   |          ------- mutable borrow later used 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();
    drop(_unit_0); // Added, to make the error reappear
}

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

由于 Rust 的限制,有什么方法可以让 push_and_get 函数工作还是不可能?如果是第一个,我怎样才能让它工作,如果是后者,是否有任何计划来解决这个特定问题,或者有什么好的理由不应该解决这个问题?

【问题讨论】:

标签: rust borrow-checker


【解决方案1】:

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

// 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 允许将 &amp;mut 转换为 &amp;,但仅限于理论上。实际上,只要您使用从可变借用创建的借用,同时进行另一个常规借用,编译器就会突然意识到,转换后的借用仍然是可变借用。类型检查器在撒谎。

总之,将 push() 和 last() 组合成一个函数是不可能的。

附:如果 Rust 将来能够支持从 &amp;mut&amp; 的真正转换,那就太好了,不会产生上述错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多