如何在Rust中创建具有默认值的HashMap?

hin*_*bug 8 rust

作为Rust的新手,我想知道如何HashMap为密钥创建一个默认值?例如,0为插入的任何键设置默认值HashMap.

在Rust中,我知道这会创建一个空的HashMap:

let mut mymap: HashMap<char, usize> = HashMap::new();
Run Code Online (Sandbox Code Playgroud)

我希望维护一组键的计数器,其中一种方法似乎是:

for ch in "AABCCDDD".chars() {
    mymap.insert(ch, 0)
}
Run Code Online (Sandbox Code Playgroud)

有没有办法在Rust中以更好的方式做到这一点,也许与Ruby提供的东西相当:

mymap = Hash.new(0)
mymap["b"] = 1
mymap["a"] # 0
Run Code Online (Sandbox Code Playgroud)

She*_*ter 15

回答问题 ......

我希望维护一组键的计数器.

那么你想看看如何有效地查找和插入HashMap?.暗示:*map.entry(key).or_insert(0) += 1


回答你问问题 ......

如何在Rust中创建具有默认值的HashMap?

不,HashMaps没有存放默认值的地方.这样做会导致该数据结构的每个用户分配空间来存储它,这将是一种浪费.您还必须处理没有适当默认值的情况,或者无法轻松创建默认值的情况.

相反,您可以使用查找值HashMap::get,如果缺少使用,则提供默认值Option::unwrap_or:

use std::collections::HashMap;

fn main() {
    let mut map: HashMap<char, usize> = HashMap::new();
    map.insert('a', 42);

    let a = map.get(&'a').cloned().unwrap_or(0);
    let b = map.get(&'b').cloned().unwrap_or(0);

    println!("{}, {}", a, b); // 42, 0
}
Run Code Online (Sandbox Code Playgroud)

当然,欢迎您将其包装在函数或数据结构中以提供更好的API.


ArtemGr提出了一个有趣的观点:

在C++中,有一个地图的概念,当访问密钥时,地图插入默认值.这总是看起来有点漏水:如果类型没有默认值怎么办?Rust对映射类型的要求较低,对键的存在(或不存在)更为明确.

Rust为此增添了额外的皱纹.实际上插入一个值需要简单地获取一个值也可以改变unwrap_or.这将使对值中的任何现有引用无效Option::unwrap_or_else,因为可能需要重新分配.因此,您不再能够同时获得对两个值的引用!那将是非常严格的.

  • 这是一个有趣的答案,因为没有默认值的原因可能很重要,但我认为这个答案将从解释如何解决OP首先*的问题中获益良多.我曾多次使用Python的`defaultdict`,我可以看到如何在Rust中实现这个"简短配方"是有价值的......实际上,你的答案实际上并没有直接提供. (2认同)

Aka*_*all 6

如何使用entry从HashMap中获取元素,然后进行修改.

来自文档:

fn entry(&mut self, key: K) -> Entry<K, V>
Run Code Online (Sandbox Code Playgroud)

获取给定键在映射中的相应条目以进行就地操作.

use std::collections::HashMap;

let mut letters = HashMap::new();

for ch in "a short treatise on fungi".chars() {
    let counter = letters.entry(ch).or_insert(0);
    *counter += 1;
}

assert_eq!(letters[&'s'], 2);
assert_eq!(letters[&'t'], 3);
assert_eq!(letters[&'u'], 1);
assert_eq!(letters.get(&'y'), None);
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

3825 次

最近记录:

6 年,6 月 前