rust实战系列

Posted lyh225

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了rust实战系列相关的知识,希望对你有一定的参考价值。

目的

本文主要围绕怎么用rust语言来设计一个cache,期间会用到闭包,泛型。

实现

use  std::cmp::Eq, hash::Hash, collections::HashMap;


struct Cacher<T, U, V> 
    where T: Fn(U) -> V 

    calculation: T,
    value: HashMap<U, V>,


上面的代码定义了一个Cacher的结构,同时使用了泛型参数T,U,V; T是一个闭包函数,输入参数U,输出参数V。
字段Cacher.calculation的类型是一个闭包函数,类型为T,Cacher.value的类型是一个hash表,用来存储闭包函数的输入和输出。

这里使用泛型参数,因此可以灵活的处理各种情况,比如

  1. 可以接受一个u32,返回u32的闭包函数
  2. 可以接受一个&str,返回其长度的闭包函数
impl<T, U, V> Cacher<T, U, V>
    where T: Fn(U) -> V, 
    U: Eq + Hash + Copy,
    V: Copy

    fn new(cal: T) -> Cacher<T, U, V> 
        Cacher 
            calculation: cal,
            value: HashMap::new()
        
    
    fn value(&mut self, value: U) -> V 
        let v = self.value.get(&value);
        match v 
            Some(v) => *v,
            None => 
                let v = (self.calculation)(value);
                self.value.insert(value, v);
                v
            
        
    


上面的代码为Cacher定义了new方法用来初始化实例,这里通过U作为Hash的key需要实现Eq和Hash两个trait。
Cacher.value 用来获取缓存的值,如果hash表有执行结果则直接返回,否则调用闭包函数计算出结果存放到hash表里面,然后
再取值返回。这里U,V也强制其要求实现Copy trait,因为value函数里面会move U,V类型的值。

**最后一个重点,Cacher::new出来的每个实例,其内部的泛型参数会在编译时实际转换为对应的类型,因此要让cacher支持不同的输入输出闭包,需要重新
Cacher::new一个实例**


#[test]
fn call_with_different_values() 
    let mut c = Cacher::new(|a| a);
    let mut d = Cacher::new(|a: &str|a.len());

    c.value(1);
    let v2 = c.value(2);
    assert_eq!(v2, 2);

    let v1 = d.value("str123");
    let v2 = d.value("str123456");
    assert_ne!(v1, v2);
    assert_eq!(v2, 9);

上面的代码分别测试了两种情况:

  1. Cacher支持不同的输入输出闭包
  2. 测试每次不同的输入,Cacher会检查是否有缓存,没有则需要重新计算并返回

总结

本文主要是在阅读<<Rust权威指南>>中的例子扩展出来的,原文的Cacher例子有两个局限性

  • 第一个问题是,Cacher实例假设value方法会为不同的arg参数返回相同的值
  • 这个Cacher实现的第二个问题是它只能接收一个获取u32类型参数并返回u32类型的值的闭包。但我们可能想要缓存的是一个获取字符串切片参数并返回usize值的闭包

以上是关于rust实战系列的主要内容,如果未能解决你的问题,请参考以下文章

[易学易懂系列|rustlang语言|零基础|快速入门|(29)|实战6:BDD工具cucumber_rust]

Rust语言入门关键技术与实战经验

rust实战

Rust 实战 |创建一个完整的项目

Rust 实战 |开发环境介绍

5分钟APIG实战: 使用Rust语言快速构建API能力开放