我想在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);
}
答案 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);
}
在文档中,K
和Q
都必须实现Hash + Eq
。
我还必须更改特征签名Q: &Sized
...这意味着我必须说:keys: &[&Q]
所以每个键都是Sized
。