如何更新可变 HashMap 中的值?

以下是我正在努力做的事情:

use std::collections::HashMap;


fn main() {
let mut my_map = HashMap::new();
my_map.insert("a", 1);
my_map.insert("b", 3);


my_map["a"] += 10;
// I expect my_map becomes {"b": 3, "a": 11}
}

但这引出了一个错误:

生锈2015

error[E0594]: cannot assign to immutable indexed content
--> src/main.rs:8:5
|
8 |     my_map["a"] += 10;
|     ^^^^^^^^^^^^^^^^^ cannot borrow as mutable
|
= help: trait `IndexMut` is required to modify indexed content, but it is not implemented for `std::collections::HashMap<&str, i32>`

Rust 2018

error[E0594]: cannot assign to data in a `&` reference
--> src/main.rs:8:5
|
8 |     my_map["a"] += 10;
|     ^^^^^^^^^^^^^^^^^ cannot assign

我真的不明白这意味着什么,因为我使 HashMap易变。当我尝试更新 vector中的一个元素时,我得到了预期的结果:

let mut my_vec = vec![1, 2, 3];


my_vec[0] += 10;
println! {"{:?}", my_vec};
// [11, 2, 3]

HashMap有什么不同,我得到上面的错误? 有没有更新值的方法?

73078 次浏览

考虑:

let mut m = std::collections::HashMap::new();
m.insert("a", 1);
m.insert("b", 3);
let k = "c";

如果密钥已经存在:

    m.insert(k, 10 + m[k] );

如果密钥不存在:

  1. 您可以更新键的值:
    m.insert(k, 10 + if m.contains_key(k) { m[k] } else { 0 });
  1. 或者首先插入一个不存在的密钥:
    m.entry(k).or_insert(0);
m.insert(k, 200 + m[k]);
  1. 或者更新密钥,防止可能未设置的密钥:
    *m.entry(k).or_insert(0) += 3000;

最后打印数值:

    println!("{}", m[k]); // 3210

参见:
Https://doc.rust-lang.org/std/collections/struct

我将分享我自己的答案,因为我有这个问题,但是我使用的是结构,所以,这种方式在我的情况下有点棘手

use std::collections::HashMap;


#[derive(Debug)]
struct ExampleStruct {
pub field1: usize,
pub field2: f64,
}


fn main() {
let mut example_map = HashMap::new();
&example_map.insert(1usize, ExampleStruct { field1: 50, field2: 184.0});
&example_map.insert(6usize, ExampleStruct { field1: 60, field2: 486.0});


//First Try
(*example_map.get_mut(&1).unwrap()).field1 += 55; //50+55=105
(*example_map.get_mut(&6).unwrap()).field1 -= 25; //60-25=35


//Spliting lines
let op_elem = example_map.get_mut(&6);
let elem = op_elem.unwrap();
(*elem).field2 = 200.0;


let op_ok_elem = example_map.get_mut(&1);
let elem = op_ok_elem.unwrap_or_else(|| panic!("This msg should not appear"));
(*elem).field2 = 777.0;


println!("Map at this point: {:?}", example_map);
let op_err_elem = example_map.get_mut(&8);
let _elem = op_err_elem.unwrap_or_else(|| panic!("Be careful, check you key"));


println!("{:?}", example_map);
}

你可以在 铁锈乐园上玩这个

你可以用 .and_modify做到这一点

let mut my_map = HashMap::new();
my_map.insert("a", 1);
my_map.entry("a").and_modify(|k| *k += 10);
assert_eq!(my_map[&"a"], 11);