我正在尝试编写一些玩具代码,用于存储它在一个单词中看到单词的次数HashMap.如果密钥存在,则将计数器递增1,如果密钥不存在,则将其与值相加1.我本能地希望用模式匹配来做这个,但是我不止一次地尝试了一个可变的错误:
fn read_file(name: &str) -> io::Result<HashMap<String, i32>> {
let b = BufReader::new(File::open(name)?);
let mut c = HashMap::new();
for line in b.lines() {
let line = line?;
for word in line.split(" ") {
match c.get_mut(word) {
Some(i) => {
*i += 1;
},
None => {
c.insert(word.to_string(), 1);
}
}
}
}
Ok(c)
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
error[E0499]: cannot borrow `c` as mutable more than once at a time
--> <anon>:21:21
|
16 | match c.get_mut(word) {
| - …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个DefaultHashMap基本上是包装器的结构,HashMap区别在于当获取不在地图中的键时,默认值将被放入该键并返回.
我做了get一个get_mut方法,这很好.现在我正在尝试实现Index并IndexMut围绕这些方法包装.在这里,我遇到了两个问题.
第一个问题是由于get当密钥不存在时必须改变结构的事实,它需要一个可变引用.然而,对于签名index的方法Index有&self代替&mut self,让我无法实现它.
这导致第二个问题,IndexMut需要Index实现.因此即使IndexMut没有实现问题,我也无法做到这一点,因为Index无法实现.
第一个问题很烦人,但可以理解.对于第二个,我不明白为什么要求就在那里.我想有办法解决它.现在我正在做以下事情,但我希望有人有更好的解决方案:
impl<K: Eq + Hash, V: Clone> Index<K> for DefaultHashMap<K, V> {
type Output = V;
fn index(&self, _: K) -> &V {
panic!("DefautHashMap doesn't implement indexing without mutating")
}
}
impl<K: Eq + Hash, V: Clone> IndexMut<K> for DefaultHashMap<K, V> {
#[inline]
fn index_mut(&mut …Run Code Online (Sandbox Code Playgroud) 这段代码:
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::collections::HashMap;
fn main() {
let mut vars = HashMap::<i32, f64>::new();
let key = 10;
let val = match vars.entry(key) {
Vacant(entry) => entry.set(0.0),
Occupied(entry) => entry.into_mut(),
};
*val += 3.4;
println!("{}", val);
}
Run Code Online (Sandbox Code Playgroud)
给出了这个错误:
error[E0599]: no method named `set` found for type `std::collections::hash_map::VacantEntry<'_, i32, f64>` in the current scope
--> src/main.rs:8:32
|
8 | Vacant(entry) => entry.set(0.0),
| ^^^
Run Code Online (Sandbox Code Playgroud)