获取对 Vec 元素的可变引用或创建新元素并获取该引用

Get mutable reference to element of Vec or create new element and get that reference

我有一个 Vec<State> 列表,我想搜索一个元素并获取对它的可变引用。如果不存在,则应创建一个新的默认元素并将其添加到列表中:

struct State {
    a: usize,
}

fn print_states(states: &Vec<State>) {
    for state in states {
        print!("State{{a:{}}} ", state.a);
    }
    println!();
}

fn main() {
    let mut states = vec![State { a: 1 }, State { a: 2 }, State { a: 3 }];

    print_states(&states);

    let mut state = match states.iter_mut().find(|state| state.a == 2) {
        Some(state) => state,
        None => {
            let new_state = State { a: 3 };
            states.push(new_state);
            states.last().unwrap()
        }
    };
    state.a = 4;
    drop(state);
    print_states(&states);
}

这导致:

error[E0594]: cannot assign to `state.a` which is behind a `&` reference
  --> src/main.rs:25:5
   |
17 |     let mut state = match states.iter_mut().find(|state| state.a == 2) {
   |         --------- help: consider changing this to be a mutable reference: `&mut State`
...
25 |     state.a = 4;
   |     ^^^^^^^^^^^ `state` is a `&` reference, so the data it refers to cannot be written

问题是 None 路径。当使用 None => panic!() 而不创建这个新的默认元素时,我可以修改找到的元素

我需要更改什么才能使这项工作正常进行?

您的问题是 state.last().unwrap() 行。 Vec returns a &State 上的方法 .last() 导致编译器将 state 的类型推断为 &State&mut State 来自 Some()-case 可以被强制转换为)。这就是为什么你不能在第 28 行更改 state

将行更改为 state.last_mut().unwrap()state 将是 &mut State 而不是 &State。您的示例在此之后编译。