美文网首页
缓存器和 deref 解引用,循环引用

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

作者: 简书网abc | 来源:发表于2022-04-27 21:01 被阅读0次
    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<T, U, V>
        where T: Fn(U) -> V
    {
        calculation: T,
        value: HashMap<U, V>,
    }
    
    impl<T, U, V> Cacher<T, U, V>
        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>(T);
    impl<T> MyBox<T> {
        fn new(x: T) -> Self {
            MyBox(x)
        }
    }
    impl<T> Deref for MyBox<T> {
        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<Weak<List>>),
        _Nil
    }
    use List::Cons;
    use List::_Nil;
    impl List {
        fn tail(&self) -> Option<&RefCell<Weak<List>>> {
            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 解引用,循环引用

          本文链接:https://www.haomeiwen.com/subject/izilyrtx.html