恢复为HashMap中的先前值

时间:2019-02-01 06:22:37

标签: hashmap rust

我正在更新HashMap中的键值,然后将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 个答案:

答案 0 :(得分:3)

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"));
        }
    }
}

答案 1 :(得分:2)

生锈的编译器对这种借用不满意,只需摆脱它

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