Взаимно заимствование в операторе совпадения и результате

Я пытаюсь определить, есть ли в контейнере объект, и вернуть найденный объект, если он есть, или добавить его, если его нет.

Я нашел Rust заимствует изменяемое выражение self внутри выражения соответствия, которое имеет ответ, в котором говорится, что то, что я пытаюсь сделать, невозможно (невозможно?) сделать.

В моей ситуации у меня есть объекты с векторами потомков. Я не хочу раскрывать внутреннюю часть своего объекта, потому что я могу изменить представление внизу.

Как Можете ли вы разрешить необходимость взаимного заимствования разных спичечных вооружений в 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);
        }
    }
}

детская площадка

Я получаю следующую ошибку:

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

person dempzorz    schedule 13.03.2018    source источник


Ответы (1)


Внесите изменение в функцию и используйте ранний возврат вместо ветки 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);
}

См. Также Изменяемое заимствование более одного раза и Как обновить или вставить в Vec?

person Jmb    schedule 13.03.2018