“不能借为可变的,因为它也借为不可变的”

时间:2019-12-15 18:54:55

标签: rust

我正在尝试计算字符串中的字符频率,并将每个字符的计数存储在BTreeMap中。但是,我收到警告,并且希望删除它。

这是我尝试过的:

use std::collections::BTreeMap;

fn letter_frequency(input: &str) -> BTreeMap<char, i32> {
    let mut tree: BTreeMap<char, i32> = BTreeMap::new();
    for item in &input.chars().collect::<Vec<char>>() {
        match tree.get(item) {
            Some(count) => tree.insert(*item, *count + 1),
            None => tree.insert(*item, 1)
        };
    }
    tree
}

这是警告:

warning: cannot borrow `tree` as mutable because it is also borrowed as immutable
 --> src/lib.rs:7:28
  |
6 |         match tree.get(item) {
  |               ---- immutable borrow occurs here
7 |             Some(count) => tree.insert(*item, *count + 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>

如何正确地将matchBTreeMap一起使用以避免错误?

1 个答案:

答案 0 :(得分:4)

就像Svetlin在评论中提到的那样,条目API是您的朋友。在下面,我还删除了一个不需要的集合。

fn letter_frequency(input: &str) -> BTreeMap<char, i32> {
    let mut tree = BTreeMap::new();
    for item in input.chars() {
        let count = tree.entry(item).or_insert(0);
        *count += 1;
    }
    tree
}

确实不需要临时变量计数:*tree.entry(item).or_insert(0) += 1;可以很好地工作,但乍看起来可能有点拥挤。