我正在更新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
我了解此错误,但是我无法弄清楚如果保存到文件失败,恢复值的正确方法是什么。
答案 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();