为什么Rust认为借用在其他分支中是活跃的

3

看起来借用检查器认为其他分支持有借用。例如

fn f(v: &mut Vec<i32>, a: bool) -> &i32 {
    match &v[0] {
        _ if a => {
            f(v, !a);
            &v[0]
        }
        x => {
            x
        }
    }
}

无法编译。

Rust Playground中查看。

错误信息如下:

error[E0502]: cannot borrow `*v` as mutable because it is also borrowed as immutable
 --> src/lib.rs:4:13
  |
1 | fn f(v: &mut Vec<i32>, a: bool) -> &i32 {
  |         - let's call the lifetime of this reference `'1`
2 |     match &v[0] {
  |            - immutable borrow occurs here
3 |         _ if a => {
4 |             f(v, !a);
  |             ^^^^^^^^ mutable borrow occurs here
...
8 |             x
  |             - returning this value requires that `*v` is borrowed for `'1`


为什么会出现这种情况,如何避免?
1个回答

4

我认为这是当前借用检查器和新的Polonius借用检查器的限制,后者将接受此问题。

通常可以通过重新排列某些控制流逻辑或者在匹配中不使用引用(而是克隆它或对复制类型进行解引用)来解决此问题。

在示例中,以下是解决方法:

fn f(v: &mut Vec<i32>, a: bool) -> &i32 {
    if a {
        f(v, !a);
    }
    &v[0]
}

或者通过使用i32Copy的事实:


或者通过使用 i32 是 Copy 的特性:
fn f(v: &mut Vec<i32>, a: bool) -> &i32 {
    match v[0] {
        _ if a => {
            f(v, !a);
            &v[0]
        }
        _ => &v[0],
    }
}

例如,第二种方法并没有太多意义,但也许对于您的用例来说,这样做会更容易/更好。

谢谢!实际的代码有些不同,但是避免了一些引用就解决了问题。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接