是否可以将HashSet用作HashMap的键?

joj*_*hua 4 hashmap rust

我想将HashSet用作的键HashMap。这可能吗?

use std::collections::{HashMap, HashSet};

fn main() {
    let hmap: HashMap<HashSet<usize>, String> = HashMap::new();
}
Run Code Online (Sandbox Code Playgroud)

给出以下错误:

use std::collections::{HashMap, HashSet};

fn main() {
    let hmap: HashMap<HashSet<usize>, String> = HashMap::new();
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 7

要使某事物成为a的键HashMap,您需要满足以下三个特征:

  1. Hash —如何计算类型的哈希值?
  2. PartialEq —如何确定一个类型的两个实例是否相同?
  3. Eq—您可以保证平等是自反的,对称的和可传递的吗?这需要PartialEq

这是基于以下定义HashMap

impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
    pub fn new() -> HashMap<K, V, RandomState> { /* ... */ }
}
Run Code Online (Sandbox Code Playgroud)

查看的文档HashSet,您可以查看其实现了哪些特征(在页面底部列出)。

没有Hashfor 的实现HashSet,因此不能用作。中的键HashMap。话虽如此,如果您有一种合理的方法来计算a的哈希HashSet,则可以围绕创建一个“新类型”,HashSet并在其上实现这三个特征。

这是“新类型”的示例:

use std::{
    collections::{HashMap, HashSet},
    hash::{Hash, Hasher},
};

struct Wrapper<T>(HashSet<T>);

impl<T> PartialEq for Wrapper<T>
where
    T: Eq + Hash,
{
    fn eq(&self, other: &Wrapper<T>) -> bool {
        self.0 == other.0
    }
}

impl<T> Eq for Wrapper<T> where T: Eq + Hash {}

impl<T> Hash for Wrapper<T> {
    fn hash<H>(&self, _state: &mut H)
    where
        H: Hasher,
    {
        // do something smart here!!!
    }
}

fn main() {
    let hmap: HashMap<Wrapper<u32>, String> = HashMap::new();
}
Run Code Online (Sandbox Code Playgroud)