如何在Rust中为延迟计算的值正确实现缓存结构?
在Rust中,我正在寻找一种更简洁、更惯用的方法来定义用于昂贵计算的缓存 在Rust编程语言第二版的第13章中,作者给读者留下了一个练习,让读者重构结构以返回延迟计算的值 经过四天的反复试验,我得出了以下结论:如何在Rust中为延迟计算的值正确实现缓存结构?,rust,Rust,在Rust中,我正在寻找一种更简洁、更惯用的方法来定义用于昂贵计算的缓存 在Rust编程语言第二版的第13章中,作者给读者留下了一个练习,让读者重构结构以返回延迟计算的值 经过四天的反复试验,我得出了以下结论: 使用std::collections::HashMap; #[允许(死代码)] 结构缓存 其中T:Fn(u32)->u32 { 计算:T, 内部:HashMap } #[允许(死代码)] impl缓存 其中T:Fn(u32)->u32 { fn新(计算:T)->缓存{ 缓存{ 计算, 内
使用std::collections::HashMap;
#[允许(死代码)]
结构缓存
其中T:Fn(u32)->u32
{
计算:T,
内部:HashMap
}
#[允许(死代码)]
impl缓存
其中T:Fn(u32)->u32
{
fn新(计算:T)->缓存{
缓存{
计算,
内部:HashMap::new(),
}
}
fn集合(&mut self,参数:u32,值:u32)->u32{
self.internal.insert(参数,值);
self.get(arg)
}
fn get(&mut self,arg:u32)->u32{
self.internal[&arg]
}
fn值(&mut self,参数:u32)->u32{
匹配self.internal.contains_键(&arg){
真=>{
self.get(arg)
},
假=>{
自我设置(arg,(自我计算)(arg))
},
}
}
}
对于测试功能:
#[测试]
fn使用不同的值调用{
让mut c=Cache::new(| a | a);
设_v1=c.值(1);
设v2=c.值(2);
断言(v2,2);
}
我可以改进这个impl
?是否有一种更为可接受的书写方式?- 在
中,set()
可以简化为self.get(arg)
value
fn value(&mut self, arg: u32) -> u32 {
let Self { internal, calculation } = self;
let entry = internal.entry(arg);
*entry.or_insert_with(|| (calculation)(arg))
}
get()
只需要一个不可变的&self
get()
和set()
从一开始似乎并没有什么帮助value()
- 您可以使用
而不是在Self
中重复结构名称impl
- 尾随逗号是好的
use std::collections::HashMap;
pub struct Cache<T>
where T: Fn(u32) -> u32
{
calculation: T,
internal: HashMap<u32, u32>,
}
impl<T> Cache<T>
where T: Fn(u32) -> u32
{
pub fn new(calculation: T) -> Cache<T> {
Self {
calculation,
internal: HashMap::new(),
}
}
pub fn value(&mut self, arg: u32) -> u32 {
let Self { internal, calculation } = self;
let entry = internal.entry(arg);
*entry.or_insert_with(|| (calculation)(arg))
}
}
#[test]
fn call_with_different_values() {
let mut c = Cache::new(|a| a);
let _v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}
使用std::collections::HashMap;
发布结构缓存
其中T:Fn(u32)->u32
{
计算:T,
内部:HashMap,
}
impl缓存
其中T:Fn(u32)->u32
{
pub fn new(计算:T)->Cache{
自我{
计算,
内部:HashMap::new(),
}
}
发布fn值(&mut self,arg:u32)->u32{
设Self{internal,calculation}=Self;
let entry=internal.entry(arg);
*条目。或插入带(| |(计算)(arg))
}
}
#[测试]
fn使用不同的值调用{
让mut c=Cache::new(| a | a);
设_v1=c.值(1);
设v2=c.值(2);
断言(v2,2);
}
也许您想要codereview.SE而不是stackoverflow?这个问题看起来有点太宽泛了。谢谢@SOFe,下次我会记住这一点的。谢谢你抽出时间把这个完整地打印出来。我特别喜欢您演示如何在
Cache::value
中使用对条目的取消引用。