【发布时间】:2022-01-20 19:26:17
【问题描述】:
我正在尝试使用 Entry 和 Rust 中的迭代器从单词数组中创建字数 HashMap。当我尝试如下时,
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word| *acc.entry(word).or_insert(0) += 1);
println!("{:?}", word_count);
}
我收到错误:预期结构 HashMap,找到 (),类型不匹配。
我可以通过创建一个新范围并将累加器显式返回为:
use std::collections::HashMap;
fn main () {
let corpus = ["foo", "bar", "bar", "grok", "blah", "foo", "bar"];
let mut word_count = corpus.iter().fold(HashMap::new(), |mut acc, word|{
*acc.entry(word).or_insert(0) += 1;
acc
});
println!("{:?}", word_count);
}
我得到了预期的{"foo": 2, "bar": 3, "blah": 1, "grok": 1}。
通常fold 返回累加器的最后状态,所以我期待第一种方法可以工作,但不清楚为什么它不工作。非常感谢您对替代方法(使用迭代器)进行一些澄清和任何建议。
【问题讨论】:
-
传入 fold 的闭包是
FnMut(B, Self::Item) -> B类型的,这意味着累加器被移动到闭包范围内(而不是作为可变引用传入),并且闭包应该返回修改后的蓄能器。表达式*acc.entry(word).or_insert(0) += 1的类型是单元类型(),因此编译器正确地将其标记为错误。 -
啊,我明白了。我是否理解正确,因为
*acc.entry(word).or_insert(0) += 1是一个语句,在第一种情况下,闭包实际上并没有返回任何东西,而它应该像在第二种情况下一样返回修改后的累加器? -
@Py_Dream 从技术上讲,这是一个返回
()的表达式,但您可以将其视为一个语句。