添加通用' contains_keys'与& [& str]和& [String]一起使用的HashMap的方法

时间:2017-05-15 04:23:05

标签: hashmap rust key

我想在contain_keys()中添加HashMap方法来测试它是否包含多个键。

我测试了以下实现:

use std::borrow::Borrow;
use std::hash::Hash;
use std::collections::HashMap;

pub trait ContainKeys<K> {
    fn contains_keys<Q>(&self, keys: &[Q]) -> bool
        where K: Borrow<Q>,
              Q: Sized + Hash + Eq + Ord;
}

impl<V> ContainKeys<String> for HashMap<String, V> {
    fn contains_keys<Q>(&self, some_keys: &[Q]) -> bool
        where String: Borrow<Q>,
              Q: Sized + Hash + Eq + Ord
    {
        some_keys.iter().all(|ref key| self.contains_key(key))
    }
}

fn main() {
    let mut map: HashMap<String, _> = HashMap::new();
    map.insert("key 1".to_string(), "value 1");
    map.insert("key 2".to_string(), "value 2");

    println!("map = {:?}", map);

    assert_eq!(map.contains_keys(&["key 1".to_string(), "key 2".to_string()]),
               true);
    assert_eq!(map.contains_keys(&["key 1".to_string(), "key 3".to_string()]),
               false);
}

自从我传递?Sized以来,我必须从原来的contain_key()方法增加到&[Q]个要求。

它编译并运行,但我发现必须将所有这些to_string()添加到密钥中非常麻烦。

是否有更好的(理想的通用)实现可以使用如下语法:

fn main() {
    let mut map: HashMap<_, _> = HashMap::new();
    map.insert("key 1", "value 1");
    map.insert("key 2", "value 2");

    println!("map = {:?}", map);

    assert_eq!(map.contains_keys(&["key 1", "key 2"]), true);
    assert_eq!(map.contains_keys(&["key 1", "key 3"]), false);
}

1 个答案:

答案 0 :(得分:0)

tl; dr,这是一个通用的解决方案,不会限制你String

use std::borrow::Borrow;
use std::hash::Hash;
use std::collections::HashMap;

pub trait ContainKeys<K: Hash + Eq> {
    fn contains_keys<Q: ?Sized>(&self, keys: &[&Q]) -> bool
        where K: Borrow<Q>,
              Q: Hash + Eq + Ord;
}

impl<V, K: Hash + Eq> ContainKeys<K> for HashMap<K, V> {
    fn contains_keys<Q: ?Sized>(&self, some_keys: &[&Q]) -> bool
        where K: Borrow<Q>,
              Q: Hash + Eq + Ord
    {
        some_keys.iter().all(|key| self.contains_key(key))
    }
}

fn main() {
    let mut map: HashMap<String, _> = HashMap::new();
    map.insert("key 1".to_string(), "value 1");
    map.insert("key 2".to_string(), "value 2");

    println!("map = {:?}", map);

    assert_eq!(map.contains_keys(&["key 1", "key 2"]), true);
    assert_eq!(map.contains_keys(&["key 1", "key 3"]), false);
}

在文档中,KQ都必须实现Hash + Eq

我还必须更改特征签名Q: &Sized ...这意味着我必须说:keys: &[&Q]所以每个键都是Sized