Rust“类型的可变性不同”

clo*_*pse 8 rust

我试图从向量中删除一个元素(如果它存在于其中):

use std::collections::HashMap;

fn test(map: HashMap<String, Vec<String>>, department: String, employee: String) {
    let &mut list = map.get(&department).unwrap();
    let index = list.iter().position(|x| x == &employee);
    match index {
        Some(i) => {
            list.remove(i);
        },
        None => {
            println!("No records of {} in {}!", &employee, &department);
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

use std::collections::HashMap;

fn test(map: HashMap<String, Vec<String>>, department: String, employee: String) {
    let &mut list = map.get(&department).unwrap();
    let index = list.iter().position(|x| x == &employee);
    match index {
        Some(i) => {
            list.remove(i);
        },
        None => {
            println!("No records of {} in {}!", &employee, &department);
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

我以为我理解错误的意思(第 170 行的 RHS 返回对向量的不可变引用),但我不太确定如何解决它。如果尝试这样的事情:

let mut list = map.get(&department).unwrap();
let index = list.iter().position(|x| x == &employee);
match index {
    Some(i) => {
        list.remove(i);
    },
    ...
}
Run Code Online (Sandbox Code Playgroud)

然后我得到

error[E0308]: mismatched types
 --> src/lib.rs:4:9
  |
4 |     let &mut list = map.get(&department).unwrap();
  |         ^^^^^^^^^   ----------------------------- this expression has type `&std::vec::Vec<std::string::String>`
  |         |
  |         types differ in mutability
  |
  = note:      expected reference `&std::vec::Vec<std::string::String>`
          found mutable reference `&mut _`
Run Code Online (Sandbox Code Playgroud)

操场

这些错误对我来说似乎有点循环,这让我觉得我需要重新思考我的设计。我将如何解决这个问题?

Joh*_*ica 7

get返回一个不可变的值Option<&V>,不允许您调用.remove(i). 用于get_mut获取可变的Option<&mut V>. 调用它要求地图本身是可变的,这表明我们正在做正确的事情。

use std::collections::HashMap;

fn test(map: &mut HashMap<String, Vec<String>>, department: String, employee: String) {
    //       ^^^^ 
    let list = map.get_mut(&department).unwrap();
    //             ^^^^^^^
    let index = list.iter().position(|x| x == &employee);
    match index {
        Some(i) => {
            list.remove(i);
        },
        None => {
            println!("No records of {} in {}!", &employee, &department);
        },
    }
}
Run Code Online (Sandbox Code Playgroud)

操场