作为一种学习练习,我想try 制作一种 map 类型(EQ.HashMap
),它有多个键,可以用几种不同的方式查找值.我以为我有一个很好的解决方案,但我很快就发现了一个明显的漏洞:
use std::borrow::Borrow;
use std::collections::HashMap;
/// Values used as keys in a Map, e.g. `HashMap<Key, _>`.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
struct Key {
session_id: usize,
screen_name: String,
}
/// Different ways to look up a value in a Map keyed by `Key`.
///
/// Each variant must constitute a unique index.
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
enum KeyQuery<'s> {
SessionId(usize),
ScreenName(&'s str),
}
impl<'s> Borrow<KeyQuery<'s>> for Key {
fn borrow(&self) -> &KeyQuery<'s> {
// ???
}
}
fn main() {
let mut map: HashMap<Key, ()> = HashMap::new();
map.insert(
Key {
session_id: 1248,
screen_name: "nombe_hombre".to_string(),
},
(),
);
// Look up values by either field of Key.
map.get(&KeyQuery::SessionId(1248));
map.get(&KeyQuery::ScreenName("nombre_hombre"));
}
简单地说,你很容易告诉拉斯特:"如果你需要一张KeyQuery::SessionId
,这里有从Key
借一张的方法."KeyQuery::ScreenName
的情况也是如此.有没有一种合理的方式来用代码来表达这一点?我不确定我是遗漏了什么明显的东西,还是遇到了类型系统的限制(可能是故意的).
Trait objects?
我已经保存了相关的问题How To Implement Hash Map With Two Keys?以备将来阅读.当我简单地通读它时,我发现自己有点超出了我的理解范围.我可以开始想象如何用实现PartialEq
、Eq
和Hash
的Key
的每个字段的方法编写一个简单的特征.不过,我不确定这是不是正确/最佳的答案.我希望有一种更直接的方法.
Just use a database?
我知道这是在突破合理的极限,简单地查询数据库可能更有意义.我仍然想学习如何最好地用铁 rust 来直接表达这个 idea .