rust - 折叠字符串以在 rust 中构建 hashmap 字符计数器,但给出两阶段借用错误
问题描述
我正在尝试建立一个计算字符串中字符频率的哈希图。我的方法是折叠字符串中的字符,在每次迭代时增加当前字符的计数。不幸的是,rust 告诉我,我在借用方面做错了。
使用clone()
或将其拆分hm.get(&c)
到单独的行没有任何影响。
我看不出如何避免这个关于两阶段借用的错误。(相关的 rust-lang github 问题)
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) {
None => hm.insert(c, 1),
Some(i) => hm.insert(c, i + 1),
};
hm
});
for (key, val) in hm.iter() {
println!("{}: {}", key, val);
}
}
这给出了这个错误
warning: cannot borrow `hm` as mutable because it is also borrowed as immutable
--> dank.rs:9:24
|
7 | match hm.get(&c) {
| -- immutable borrow occurs here
8 | None => hm.insert(c, 1),
9 | Some(i) => hm.insert(c, i+1)
| ^^ - immutable borrow later used here
| |
| mutable borrow occurs here
|
= note: `#[warn(mutable_borrow_reservation_conflict)]` on by default
= warning: this borrowing pattern was not meant to be accepted, and may become a hard error in the future
= note: for more information, see issue #59159 <https://github.com/rust-lang/rust/issues/59159>
解决方案
感谢@Stargateur 回答我的问题
问题是,当我们i + 1
重新插入 hashmap 时,变量i
实际上是从 hashmap 借来的。如果我们首先复制 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);
}
}
推荐阅读
- ios - 我可以测量从 iPhone 后置摄像头到物体的距离吗?
- tensorflow - AttributeError:“str”对象没有属性“base_dtype”
- python - pytorch 在 tensorflow 中的 autograd.detect_anomaly 等效项
- material-ui - 我可以在同一个 Next js 项目中使用 Tailwind CSS 和 Material UI 吗?
- python - Django rest框架:页面刷新后cookie丢失
- opencv - 如何使用 OpenCV 计算 3D 透视变换矩阵
- firebase - 未填写实时数据库中的日期类
- c# - Visual Studio 在我的代码中随机添加了很多空格
- php - 如何从 WP travel 插件自定义结帐页面
- arrays - 从数组中删除索引号