代码之家  ›  专栏  ›  技术社区  ›  dempzorz

匹配语句和结果中的可变借用

  •  2
  • dempzorz  · 技术社区  · 6 年前

    我试图确定容器是否有对象,如果有,则返回找到的对象,如果没有,则添加。

    我找到了 Rust borrow mutable self inside match expression 有一个答案说我想做的事不能(不能?)完成。

    在我的情况下,我有一些物体有子向量。我不想暴露对象的内部,因为我可能想更改下面的表示。

    How can you resolve the need to mutably borrow in different match arms in Rust? 似乎在暗示,如果我的生命周期正确的话,我也许可以做我想做的事情,但我还没有弄清楚怎么做。

    以下是我面临的问题的陈述:

    fn find_val<'a>(container: &'a mut Vec<i32>, to_find: i32) -> Option<&'a mut i32> {
        for item in container.iter_mut() {
            if *item == to_find {
                return Some(item);
            }
        }
    
        None
    }
    
    fn main() {
        let mut container = Vec::<i32>::new();
        container.push(1);
        container.push(2);
        container.push(3);
    
        let to_find = 4;
    
        match find_val(&mut container, to_find) {
            Some(x) => {
                println!("Found {}", x);
            }
            _ => {
                container.push(to_find);
                println!("Added {}", to_find);
            }
        }
    }
    

    playground

    我得到的错误是:

    error[E0499]: cannot borrow `container` as mutable more than once at a time
      --> src/main.rs:24:13
       |
    19 |     match find_val(&mut container, to_find) {
       |                         --------- first mutable borrow occurs here
    ...
    24 |             container.push(to_find);
       |             ^^^^^^^^^ second mutable borrow occurs here
    ...
    27 |     }
       |     - first borrow ends here
    
    1 回复  |  直到 6 年前
        1
  •  2
  •   Shepmaster Tim Diekmann    6 年前

    将更改放在函数中,并使用早期返回而不是 else 分支机构:

    fn find_val_or_insert(container: &mut Vec<i32>, to_find: i32) {
        if let Some(x) = find_val(&container, to_find) {
            println!("Found {}", x);
            return; // <- return here instead of an else branch
        }
        container.push(to_find);
        println!("Added {}", to_find);
    }
    

    另请参见 Mutable borrow more than once How to update-or-insert on a Vec?