ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【Rust】使用HashMap解决官方文档中的闭包限制

2022-05-14 20:31:54  阅读:184  来源: 互联网

标签:闭包 HashMap value Cacher arg new Rust u32


问题概述

值缓存是一种更加广泛的实用行为,我们可能希望在代码中的其他闭包中也使用他们。然而,目前 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

测试通过

标签:闭包,HashMap,value,Cacher,arg,new,Rust,u32
来源: https://www.cnblogs.com/hoseacube/p/16271390.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有