[英]How can I update a value in a mutable HashMap?
Here is what I am trying to do:这是我想要做的:
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}
}
But this raises an error:但这引发了一个错误:
Rust 2015锈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铁锈 2018
error[E0594]: cannot assign to data in a `&` reference
--> src/main.rs:8:5
|
8 | my_map["a"] += 10;
| ^^^^^^^^^^^^^^^^^ cannot assign
I don't really understand what that means, since I made the HashMap
mutable.我真的不明白这意味着什么,因为我使
HashMap
可变。 When I try to update an element in a vector
, I get the expected result:当我尝试更新
vector
的元素时,我得到了预期的结果:
let mut my_vec = vec![1, 2, 3];
my_vec[0] += 10;
println! {"{:?}", my_vec};
// [11, 2, 3]
What is different about HashMap
that I am getting the above error?我收到上述错误的
HashMap
有什么不同? Is there a way to update a value?有没有办法更新一个值?
Indexing immutably and indexing mutably are provided by two different traits: Index
and IndexMut
, respectively.不可变索引和可变索引由两个不同的特征提供:分别是
Index
和IndexMut
。
Currently, HashMap
does not implement IndexMut
, while Vec
does .目前,
HashMap
没有实现IndexMut
,而Vec
实现了。
The commit that removed HashMap
's IndexMut
implementation states:删除
HashMap
的IndexMut
实现的提交声明:
This commit removes the IndexMut impls on HashMap and BTreeMap, in order to future-proof the API against the eventual inclusion of an IndexSet trait.
此提交删除了 HashMap 和 BTreeMap 上的 IndexMut 实现,以便将来证明 API 不会最终包含 IndexSet 特征。
It's my understanding that a hypothetical IndexSet
trait would allow you to assign brand-new values to a HashMap
, and not just read or mutate existing entries:我的理解是,假设的
IndexSet
特征将允许您为HashMap
分配全新的值,而不仅仅是读取或更改现有条目:
let mut map = HashMap::new();
map["key"] = "value";
For now, you can use get_mut
:现在,您可以使用
get_mut
:
*my_map.get_mut("a").unwrap() += 10;
*my_map.entry("a").or_insert(42) += 10;
Considering:考虑:
let mut m = std::collections::HashMap::new();
m.insert("a", 1);
m.insert("b", 3);
let k = "c";
If the key already exists:如果密钥已经存在:
m.insert(k, 10 + m[k] );
If the key not exists:如果密钥不存在:
m.insert(k, 10 + if m.contains_key(k) { m[k] } else { 0 });
m.entry(k).or_insert(0);
m.insert(k, 200 + m[k]);
*m.entry(k).or_insert(0) += 3000;
Finally print the value:最后打印值:
println!("{}", m[k]); // 3210
See:看:
https://doc.rust-lang.org/std/collections/struct.HashMap.html https://doc.rust-lang.org/std/collections/struct.HashMap.html
I will share my own Answer because I had this issue but I was working with Structs so, that way in my case was a little bit tricky我将分享我自己的答案,因为我遇到了这个问题,但我正在使用 Structs,所以在我的情况下,这种方式有点棘手
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);
}
You can play with this on Rust Playground你可以在Rust Playground上玩这个
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.