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

Why does rust consider borrows active in other branches

借款检查员似乎认为其他分支机构持有借款。例如

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`

为什么会这样,我该如何解决?

我认为这是当前借用检查器的一个限制,新的 Polonius 会接受这个。

通常通过重新安排一些控制流逻辑或不在匹配中使用引用(克隆它或取消引用副本类型)来解决这个问题。

在这个例子中,你是这样绕过它的:

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

或者利用 i32Copy 的事实:

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

例如,第二种方法没有太大意义,但对于您的用例来说,这样做可能是 easier/nicer。