当键没有实现克隆特征时记忆
Memoize when key does not implement Clone trait
在下面的惰性记忆示例中,当键未实现 Clone
特征时,如何 return 记忆值?
在下面的实现中,由于键的值已经被移动,我们如何使用给定的键再次从存储中查询值?
当 key 没有实现 clone trait 时,有没有更好的方法来编写这段代码?
struct Cacher<T, Y>
where
T: Fn(&Y) -> Y,
Y: Eq + Hash,
{
store: HashMap<Y, Y>,
compute: T,
}
impl<T, Y> Cacher<T, Y>
where
T: Fn(&Y) -> Y,
Y: Eq + Hash,
{
fn new(comp: T) -> Self {
Cacher {
compute: comp,
store: HashMap::new(),
}
}
fn get(&mut self, key: Y) -> Option<&Y> {
if self.store.contains_key(&key) {
self.store.get(&key)
} else {
let value = (self.compute)(&key);
self.store.insert(key, value);
self.store.get(&key) //<---- This is problematic
}
}
}
使用条目 API:
fn get(&mut self, key: Y) -> &Y {
if self.store.contains_key(&key) {
self.store.get(&key).unwrap()
} else {
let value = (self.compute)(&key);
match self.store.entry(key) {
Entry::Occupied(entry) => unreachable!(),
Entry::Vacant(entry) => entry.insert(value)
}
}
}
但是,此时单独使用条目 API 更好(并且性能更高):
fn get(&mut self, key: Y) -> &Y {
match self.store.entry(key) {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = (self.compute)(entry.key());
entry.insert(value)
}
}
}
或者使用组合器:
fn get(&mut self, key: Y) -> &Y {
self.store.entry(key).or_insert_with_key(&self.compute)
}
在下面的惰性记忆示例中,当键未实现 Clone
特征时,如何 return 记忆值?
在下面的实现中,由于键的值已经被移动,我们如何使用给定的键再次从存储中查询值?
当 key 没有实现 clone trait 时,有没有更好的方法来编写这段代码?
struct Cacher<T, Y>
where
T: Fn(&Y) -> Y,
Y: Eq + Hash,
{
store: HashMap<Y, Y>,
compute: T,
}
impl<T, Y> Cacher<T, Y>
where
T: Fn(&Y) -> Y,
Y: Eq + Hash,
{
fn new(comp: T) -> Self {
Cacher {
compute: comp,
store: HashMap::new(),
}
}
fn get(&mut self, key: Y) -> Option<&Y> {
if self.store.contains_key(&key) {
self.store.get(&key)
} else {
let value = (self.compute)(&key);
self.store.insert(key, value);
self.store.get(&key) //<---- This is problematic
}
}
}
使用条目 API:
fn get(&mut self, key: Y) -> &Y {
if self.store.contains_key(&key) {
self.store.get(&key).unwrap()
} else {
let value = (self.compute)(&key);
match self.store.entry(key) {
Entry::Occupied(entry) => unreachable!(),
Entry::Vacant(entry) => entry.insert(value)
}
}
}
但是,此时单独使用条目 API 更好(并且性能更高):
fn get(&mut self, key: Y) -> &Y {
match self.store.entry(key) {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => {
let value = (self.compute)(entry.key());
entry.insert(value)
}
}
}
或者使用组合器:
fn get(&mut self, key: Y) -> &Y {
self.store.entry(key).or_insert_with_key(&self.compute)
}