首页 > 解决方案 > 恢复到 HashMap 中的先前值

问题描述

我正在更新 a 中的键值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

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

标签: hashmaprust

解决方案


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

推荐阅读