кредит @Stargateur за ответ на мой вопрос
Проблема заключалась в том, что когда мы вставляем i + 1
обратно в хэш-карту, переменная i
фактически заимствуется из хэш-карты . Если мы сначала скопируем i, наш неизменный заем hm
заканчивается там, где мы копируем i
, то есть до того, как мы используем изменяемую ссылку на hm
для insert()
.
use std::collections::HashMap;
fn main() {
let some_str = "some string";
let hm = some_str.chars().fold(HashMap::new(), |mut hm, c| {
match hm.get(&c) { // borrow of hm
None => hm.insert(c, 1),
Some(i) => { // i is a reference
let j = *i; // i is Copy so we copy it, j is not a reference owned by hm, so hm is not borrowed anymore
hm.insert(c, j + 1) // we can borrow hm mutable
}
};
hm
});
for (key, val) in hm.iter() {
println!("{}: {}", key, val);
}
}
Далее, лучшее решение - использовать Entry api , чтобы полностью обойти эту проблему с помощью следующего кода:
use std::collections::HashMap;
fn main() {
let some_str = "some string";
let hm = some_str.chars().fold(HashMap::new(), |mut hm, c| {
*hm.entry(c).or_insert(0) += 1;
hm
});
for (key, val) in hm.iter() {
println!("{}: {}", key, val);
}
}