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

问题描述 投票:8回答:2

作为Rust的新手,我想知道如何使用密钥的默认值创建HashMap?例如,对于插入0中的任何键,具有默认值HashMap

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

let mut mymap: HashMap<char, usize> = HashMap::new();

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

for ch in "AABCCDDD".chars() {
    mymap.insert(ch, 0)
}

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

mymap = Hash.new(0)
mymap["b"] = 1
mymap["a"] # 0
rust
2个回答
13
投票

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

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

然后你想看看How to lookup from and insert into a HashMap efficiently?。提示:*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
}

如果unwrap_or不适合你的情况,有几个类似的功能可能:

当然,欢迎来到wrap this in a function or a data structure to provide a nicer API


ArtemGr brings up an interesting point

在C ++中有一个地图inserting a default value when a key is accessed的概念。这总是看起来有点漏水:如果类型没有默认值怎么办? Rust对映射类型的要求较低,对键的存在(或不存在)更为明确。

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


6
投票

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

来自文档:

fn entry(&mut self, key: K) -> Entry<K, V>

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

example

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);
© www.soinside.com 2019 - 2024. All rights reserved.