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());
}
网友评论