Rust实现简单的IOC容器
use std::{any::{Any, TypeId}, collections::HashMap};
use once_cell::sync::Lazy;
use std::sync::Mutex;
static IOC: Lazy<Mutex<HashMap<TypeId, Box<(dyn Any + Send)>>>> = Lazy::new(|| {
let map = HashMap::new();
Mutex::new(map)
});
#[derive(Debug)]
struct Foo {
cat: String,
mouse: i32,
}
#[derive(Debug)]
struct Bar {
pro1: String,
pro2: i32,
pro3: f64
}
fn main() {
// 这里insert后应该就把锁释放了,但是为啥get不能这么写还得再学习下原理【估计是这里自动会加一个{}作用域,而get加了这个作用域导致获取的
// 变量也在隐藏的作用域结束后释放了,所以产生了报错,提示临时变量已经被释放之类的错误
IOC.lock().unwrap().insert(TypeId::of::<Foo>(), Box::new(Foo{cat: "aa".to_string(), mouse: 33}));
// 上面的语句应该是会转换成这样,因此get得到的tmp_get会释放了,所以后续是无法用tmp_get的;
/* {
let tmp = IOC.lock.unwrap();
tmp.insert(TypeId::of::<Foo>(), Box::new(Foo{cat: "aa".to_string(), mouse: 33}));
} */
IOC.lock().unwrap().insert(TypeId::of::<Bar>(), Box::new(Bar{pro1: "bb".to_string(), pro2: 66, pro3: 99.4}));
{
// 加了{}是为了让这个ioc_tmp在{}后释放锁,否则{}下面的removed_bar里的IOC.lock().unwrap()会一直等待锁释放来加锁【非可重入锁】
// 所以rust其实也不是完全的线程安全,只能说常见的场景会限制;
let ioc_tmp = IOC.lock().unwrap();
let foo = ioc_tmp.get(&TypeId::of::<Foo>()).unwrap();
let casted_foo = foo.downcast_ref::<Foo>();
let bar = ioc_tmp.get(&TypeId::of::<Bar>()).unwrap();
let casted_bar = bar.downcast_ref::<Bar>();
println!("{:?}--{:?}", casted_foo, casted_bar);
}
// remove会获取value的所有权,所以函数结束后会释放掉removed_bar
let removed_bar = IOC.lock().unwrap().remove(&TypeId::of::<Bar>()).unwrap();
let removed_bar = removed_bar.downcast_ref::<Bar>();
println!("{:?}", removed_bar);
{
let ioc_tmp = IOC.lock().unwrap();
let none_bar = ioc_tmp.get(&TypeId::of::<Bar>());
println!("{:?}", none_bar);
}
}
posted on 2022-10-09 15:54 Silentdoer 阅读(318) 评论(0) 编辑 收藏 举报