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

还原到HashMap中的上一个值

  •  0
  • seladb  · 技术社区  · 6 年前

    我正在更新 HashMap 然后保存 归档。我想确保,如果保存到文件失败,则恢复更新。这是我写的代码( Rust Playground ):

    use std::collections::HashMap;
    use std::fs;
    extern crate serde_json; // 1.0.37
    
    fn save_map_to_file(map: &HashMap<String, String>) -> Result<(), ()> {
        // serialize map to json
        let map_as_string = match serde_json::to_string(map) {
            Ok(json_map) => json_map,
            Err(_) => return Err(()),
        };
    
        // write the json to a file
        match fs::write("map.bin", map_as_string) {
            Ok(_) => Ok(()),
            Err(_) => Err(()),
        }
    }
    
    fn change_map(map: &mut HashMap<String, String>) {
        // save current value in "key1" (if exists)
        let val = map.get("key1");
    
        // insert a new value to "key1"
        map.insert(String::from("key1"), String::from("value2"));
    
        // try to save the map to a file
        match save_map_to_file(map) {
            Ok(_) => (),
            Err(_) => {
                // if save fails, revert back to the original value
                match val {
                    Some(value) => {
                        // if "key1" existed before the change, revert back to
                        // original value
                        map.insert(String::from("key1"), value.to_string());
                    }
    
                    None => {
                        // if "key1" didn't exist before the change, remove the
                        // new "key1"->"value2" record
                        map.remove("key1");
                    }
                }
                ()
            }
        }
    }
    
    fn main() {
        let mut map: HashMap<String, String> = HashMap::new();
    
        map.insert(String::from("key1"), String::from("value1"));
    
        change_map(&mut map);
    
        println!("Map: {:?}", map);
    }
    

    error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
      --> src/main.rs:24:5
       |
    21 |     let val = map.get("key1");
       |               --- immutable borrow occurs here
    ...
    24 |     map.insert(String::from("key1"), String::from("value2"));
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
    ...
    31 |             match val {
       |                   --- immutable borrow later used here
    

    我理解这个错误,但是如果保存到文件失败,我无法找出恢复值的正确方法。

    2 回复  |  直到 6 年前
        1
  •  3
  •   Shepmaster Tim Diekmann    6 年前

    insert() 返回以前的值(如果有的话),这样代码就可以简化很多。这也解决了您的借款问题:

    fn change_map(map: &mut HashMap<&str, String>) {
        let previous = map.insert("key1", String::from("value2"));
        match save_map_to_file(map) {
            Ok(_) => (),
            Err(_) => {
                previous
                    .and_then(|previous| map.insert("key1", previous))
                    .or_else(|| map.remove("key1"));
            }
        }
    }
    
        2
  •  2
  •   Shepmaster Tim Diekmann    6 年前

    --- let val = map.get("key1");
    +++ let val = map.get("key1").cloned();