【Rust】使用HashMap解决官方文档中的闭包限制
问题概述
值缓存是一种更加广泛的实用行为,我们可能希望在代码中的其他闭包中也使用他们。然而,目前 Cacher 的实现存在两个小问题,这使得在不同上下文中复用变得很困难。
第一个问题是 Cacher 实例假设对于 value 方法的任何 arg 参数值总是会返回相同的值。也就是说,这个 Cacher 的测试会失败:
《rust程序设计语言》13章闭包内容提出的问题
#[test]
fn call_with_different_values() {
let mut c = Cacher::new(|a| a);
let v1 = c.value(1);
let v2 = c.value(2);
assert_eq!(v2, 2);
}
具体代码请在《rust程序设计语言》第13章第一节 Cacher 实现的限制 中找到。
解决思路
尝试修改 Cacher 存放一个哈希 map 而不是单独一个值。哈希 map 的 key 将是传递进来的 arg 值,而 value 则是对应 key 调用闭包的结果值。
相比之前检查 self.value 直接是 Some 还是 None 值,现在 value 函数会在哈希 map 中寻找 arg,如果找到的话就返回其对应的值。如果不存在,Cacher 会调用闭包并将结果值保存在哈希 map 对应 arg 值的位置。
《rust程序设计语言》13章闭包内容提出的解决思路
解决方案
更改Cacher结构体的类型
use std::collections::HashMap;
struct Cacher<T>
where
T: Fn(u32) -> u32,
{
calculation: T,
value: HashMap<u32, u32>,
}
将之前储存单一u32类型的 value字段 替换成 HashMap类型,此HashMap的key和value都为u32类型。
更改chacher结构体的方法
impl<T> Cacher<T>
where
T: Fn(u32) -> u32,
{
fn new(calculation: T) -> Cacher<T> {
Cacher {
calculation,
value: HashMap::new(),
}
}
fn value(&mut self, arg: u32) -> u32 {
match self.value.get(&arg) {
Some(v) => *v,
None => {
let v = (self.calculation)(arg);
self.value.insert(arg, v);
arg
}
}
}
}
new方法中返回的Cacher实例,value字段 不再为Option<u32>类型,取而代之的是一个 被初始化的HashMap,用于存放 不同参数的结果缓存。
value方法中,不再直接匹配结构体的value字段,而是通过 参数 去value字段的 HashMap 中找到储存的值并返回,要是找不到则在HashMap中插入 key值为传入参数,value值为结构体闭包调用参数所得的结果。
测试结果
fn main() {
let mut cal = Cacher::new(|num| {
println!("calculating slowly...");
thread::sleep(Duration::from_secs(2));
num
});
println!("{}", cal.value(1));
println!("{}", cal.value(2));
println!("{}", cal.value(1))
}
cargo run
Compiling closure v0.1.0 (D:\project\rust\closure)
Finished dev [unoptimized + debuginfo] target(s) in 0.66s
Running `target\debug\closure.exe`
calculating slowly...
1
calculating slowly...
2
1
测试通过
【Rust】使用HashMap解决官方文档中的闭包限制的更多相关文章
- swift官方文档中的函数闭包是怎么理解的?
官方文档中的16页: numbers.map({ (number: Int) -> Int in let result = * number return result }) 不知道这个怎么用, ...
- swift官方文档中的switch中case let x where x.hasSuffix("pepper")是什么意思?
在官方文档中,看到这句.但不明白什么意思. let vegetable = "red pepper" switch vegetable { case "celery&qu ...
- 从官方文档中探索MySQL分页的几种方式及分页优化
概览 相比于Oracle,SQL Server 等数据库,MySQL分页的方式简单得多了,官方自带了分页语法 limit 语句: select * from test_t LIMIT {[offset ...
- tensorflow官方文档中的sub 和mul中的函数已经在API中改名了
在照着tensorflow 官方文档和极客学院中tensorflow中文文档学习tensorflow时,遇到下面的两个问题: 1)AttributeError: module 'tensorflow' ...
- 【采坑小计】thanos receiver的官方文档中,并未说明tsdb落盘的配置方式
官方文档的地址在:https://thanos.io/tip/components/receive.md/ 一开始以为落盘的时间间隔是:--tsdb.retention=15d 实际测试中发现,tha ...
- 【原创+译文】官方文档中声明的如何创建抽屉导航栏(Navigation Drawer)
如需转载请注明出处:http://www.cnblogs.com/ghylzwsb/p/5831759.html 创建一个抽屉导航栏 抽屉式导航栏是显示在屏幕的左边缘,它是应用程序的主导航选项面板.它 ...
- Django1.7官方文档中的tutorial——翻译
写下你的第一个Django应用,第一部分 让我们通过例子来学习. 通过这篇指南,我们将会带你浏览一遍一个基本投票应用的创建. 它由两部分组成: 1一个让人们查看投票和进行投票的公共站点 2一个让你添加 ...
- Vue官方文档中的camelCased (驼峰式) 命名与 kebab-case
因为html特性中 元素的 prop是不区分大小写的 所以不管html中怎么大写小写变化,下面的组件的prop应该写成小写 Vue中有这样一种设定: props中如果使用为kebab-case命名方式 ...
- 摘录ECMAScript官方文档中重要的两段话
Every object created by a constructor has an implicit reference (called the object’s prototype) to t ...
随机推荐
- Java基础学习之“二维数组”
一.鄙人对二维数组的理解 二维数组就是由多个数组并列而成 二.举例 1.普通数组(一维数组)的图像格式 2.二维数组的图像格式 代码 1 @Test 2 public void xueXi(){ 3 ...
- HMS Core 分析服务 6.4.1版本上线啦,快来看看更新了哪些内容。
更新概览 支持转化事件回传至华为应用市场商业推广,便捷归因,实时调优. 卸载分析模型支持用户卸载前事件和路径分析,深度剖析卸载根因. 实时漏斗体验开放,灵活定位异常流失. 详情介绍 更新一:全面开放深 ...
- python学习笔记(二)——程序结构
1. 选择结构: if 语句:单分支.双分支.多分支 **单分支结构** if 条件表达式: 语句块 **双分支结构** if 条件表达式: 语句块 else: 语句块 **多分支结构** if 条件 ...
- 知网上的硕士和博士论文怎么下载pdf格式
文献管理使用的EndNote,阅读习惯使用Drawboard,在下载硕士和博士论文时在知网上只能下载caj格式,于是就想找一种能下载pdf的方式. 知乎中有篇文章介绍的如何下载pdf的方法,很管用也很 ...
- circle_clock 简单canvas实现圆弧时钟
渣渣成品图:http://codepen.io/thewindswor... 最近对于圆形有种特别的感情呢...因为写了个cricle_process_bar就像到了用来做时钟大概会比较有趣吧,所以就 ...
- 检查浏览器支持Webp
什么是Webp? Webp 是一种支持有损压缩和无损压缩的图片文件格式,派生自图像编码格式 VP8.根据 Google 的测试,无损压缩后的 WebP 比 PNG 文件少了 45% 的文件大小,即使这 ...
- nodejs 实现 磁力链接资源搜索 BT磁力链接爬虫
项目简介 前端站点 项目效果预览 http://findcl.com 使用 nodejs 实现磁力链接爬虫 磁力链接解析成 torrent种子信息,保存到数据库,利用 Elasticsearch 实现 ...
- java的原子类到底是啥?ABA,CAS又是些什么?
1)解决并发不是用锁就能解决吗,那SDK干嘛还要搞个原子类出来? 锁虽然能解决,但是加锁解锁始终还是对性能是有影响的,并且使用不当可能会造成死锁之类的问题. 2)原子类是怎样使用的,比如说我要实现一个 ...
- 技术管理进阶——什么Leader值得追随?
原创不易,求分享.求一键三连 Leader眼里的主动性 前几天孙狗下面小A身上发生了一件Case,让他感到很疑惑: 有一个跨部门较多的项目推进不力,于是善于交流的他被临时提拔成项目负责人,但马上令人 ...
- 函数 装饰器 python
今日内容概要 1.闭包函数 2.闭包函数的实际应用 3.装饰器简介(重点加难点) 4.简易版本装饰器 5.进阶版本装饰器 6.完整版本装饰器 7.装饰器模板(拷贝使用即可) 8.装饰器语法糖 9.装饰 ...