在這種情況下,最簡單的解決是像一個垃圾收集語言將工作:
use std::collections::HashMap;
use std::rc::Rc;
use std::hash::Hash;
use std::ops::Deref;
struct BidiMap<A, B> {
left_to_right: HashMap<Rc<A>, Rc<B>>,
right_to_left: HashMap<Rc<B>, Rc<A>>,
}
impl<A, B> BidiMap<A, B>
where
A: Eq + Hash,
B: Eq + Hash,
{
fn new() -> Self {
BidiMap {
left_to_right: HashMap::new(),
right_to_left: HashMap::new(),
}
}
fn put(&mut self, a: A, b: B) {
let a = Rc::new(a);
let b = Rc::new(b);
self.left_to_right.insert(a.clone(), b.clone());
self.right_to_left.insert(b, a);
}
fn get(&self, a: &A) -> Option<&B> {
self.left_to_right.get(a).map(Deref::deref)
}
fn get_reverse(&self, b: &B) -> Option<&A> {
self.right_to_left.get(b).map(Deref::deref)
}
}
fn main() {
let mut map = BidiMap::new();
map.put(1, 2);
println!("{:?}", map.get(&1));
println!("{:?}", map.get_reverse(&2));
}
當然,你想有多少更嚴格代碼,因爲這可以讓你打破雙向映射。這只是向您展示解決問題的一種方式。
顯然,其中一人有自己的數據
顯然,這不是真正的^ _ ^。在這種情況下,兩張地圖共享所有權使用Rc
。
Benchmark此解決方案知道它是否足夠有效。
做更有效率的事情需要更多的關於所有權的思考。例如,如果left_to_right
地圖擁有數據,並且您在另一個地圖中使用了一個原始指針,那麼只要重新分配第一個地圖,該指針就會失效。
如果因爲需要修改其中一個值而想要獲取可變引用,該怎麼辦? – khc
@khc然後你需要[內部可變性](https://doc.rust-lang.org/stable/std/cell/)。 – Shepmaster