我的目标是实施建议的改进缓存结构Rust 书第 13.1 章的内容是,创建一个结构体,该结构体接受一个函数并使用记忆来减少给定函数的调用次数。为此,我创建了一个结构体HashMap
struct Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash
{
calculation: T,
map: HashMap<U,V>,
}
和两种方法,一种是构造函数,另一种负责记忆。
impl<T, U, V> Cacher<T, U, V>
where T: Fn(&U) -> V, U: Eq + Hash
{
fn new(calculation: T) -> Cacher<T,U,V> {
Cacher {
calculation,
map: HashMap::new(),
}
}
fn value(&mut self, arg: U) -> &V {
match self.map.entry(arg){
Entry::Occupied(occEntry) => occEntry.get(),
Entry::Vacant(vacEntry) => {
let argRef = vacEntry.key();
let result = (self.calculation)(argRef);
vacEntry.insert(result)
}
}
}
}
我用的是Entry枚举,因为我没有找到更好的方法来决定是否HashMap包含一个键,如果不包含,则计算该值并将其插入到 HashMap 中并返回对其的引用。
如果我想编译上面的代码,我会收到一条错误消息occEntry被它借用了.get()方法(这对我来说很好).get() “返回引用当前函数拥有的数据的值”.
我的理解是编译器认为该值occEntry.get()引用的是函数所拥有的价值(...)。但我不应该得到类型 V 的值的引用吗,它的所有者是HashMap?编译器是否会感到困惑,因为该值由函数拥有并保存为result一会儿?
let result = (self.calculation)(argRef);
vacEntry.insert(result)
请注意,需要暂时保存结果,因为insert方法消耗密钥等argRef不再有效。我也承认签名value可能会出现问题(请参阅从 HashMap 中可变借用和生命周期省略 https://stackoverflow.com/questions/56181266/mutable-borrow-from-hashmap-and-lifetime-elision)但我试图避免Copy特质绑定。
为了快速重现问题,我附加了使用语句必要的。感谢您的帮助。
use std::collections::HashMap;
use std::cmp::Eq;
use std::hash::Hash;
use std::collections::hash_map::{OccupiedEntry, VacantEntry, Entry};