缓存器和 deref 解引用,循环引用

1, 使用闭包和泛型实现简单的Cache

这里U,V也强制其要求实现Copy trait,因为value函数里面会move U,V类型的值。
最后一个重点,Cacher::new 出来的每个实例,其内部的泛型参数会在编译时实际转换为对应的类型,因此要让cacher支持不同的输入输出闭包,需要重新 Cacher::new一个实例


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

struct Cacher
    where T: Fn(U) -> V
{
    calculation: T,
    value: HashMap,
}

impl Cacher
    where T: Fn(U) -> V,
          U: Eq + Hash + Copy,
          V: Copy
{
    fn new(cal: T) -> Self {
        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
            }
        }
    }
}
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(1);
    println!("v22: {}", v2);

    let v1 = d.value("str123");
    let v2 = d.value("str123456");
    println!("v1: {}", v1);
    println!("v2: {}", v2);
}

fn main() {
    println!("ok");
    call_with_different_values();
}

2. 自定义解引用

use std::ops::Deref;

struct MyBox(T);
impl MyBox {
    fn new(x: T) -> Self {
        MyBox(x)
    }
}
impl Deref for MyBox {
    type  Target = T;
    fn deref(&self) -> &T {
        &self.0
    }
}


fn main() {
    let x = 5;
    let y = MyBox::new(x);

    println!("{}", *y);
}

3. 循环引用

use std::cell::RefCell;
use std::rc::{Weak, Rc};

#[derive(Debug)]
enum List {
    Cons(i32, RefCell>),
    _Nil
}
use List::Cons;
use List::_Nil;
impl List {
    fn tail(&self) -> Option<&RefCell>> {
        match self {
            Cons(_, item) => Option::Some(item),
            _Nil=> Option::None,
        }
    }
}

fn main() {
    let a = Rc::new(Cons(5, RefCell::new(Weak::new())));
    println!("1, a strong count: {}, weak count: {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("1, a.tail() = {:?}", a.tail());

    let b = Rc::new(Cons(10, RefCell::new(Weak::new())));
    if let Some(link_b) = b.tail() {
        *link_b.borrow_mut() = Rc::downgrade(&a);
    }
    println!("2, a strong count: {}, weak count: {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("2, b strong count: {}, weak count: {}", Rc::strong_count(&b), Rc::weak_count(&b));
    println!("2, a.tail() = {:?}", a.tail());
    if let Option::Some(link_a) = a.tail() {
        *link_a.borrow_mut() = Rc::downgrade(&b);
    }
    println!("3, a strong count: {}, weak count: {}", Rc::strong_count(&a), Rc::weak_count(&a));
    println!("3, b strong count: {}, weak count: {}", Rc::strong_count(&b), Rc::weak_count(&b));
    println!("3, a.tail() = {:?}", a.tail());
}

你可能感兴趣的:(缓存器和 deref 解引用,循环引用)