问题描述
假设我们有一个由 lazy_static 创建的 trait 对象的全局可访问哈希图:navbar
,其中 MY_ANIMALS: Mutex<HashMap<i32,AnimalBox>>
现在,我们希望这个全局哈希图中的动物能够相互交互。例如,一个 type AnimalBox = Box<dyn AnimalExt+Send>
可以AnimalBox
另一个。
问题是我们的 AnimalExt::eat(&mut self,prey: &mut AnimalBox)
函数既需要对 self 的可变引用,也需要对祈祷的可变引用(因为我们希望祈祷在被吃掉时 eat()
。
但是,获得对我们的哈希图的两个可变引用会导致 AnimalExt::perish(&mut self)
错误:
WouldBlock
有什么好的解决方法吗?或者有没有安全的方法可以用哈希图来做到这一点?我对类似的问题有 seen this answer,但建议的答案建议使用 use lazy_static::lazy_static;
use std::sync::Mutex;
use std::collections::HashMap;
//type alias for our boxed animals
type AnimalBox = Box<dyn AnimalExt+Send>;
//globally accessible hashmap for keeping track of our animals throughout the scope of our application
lazy_static! {
static ref MY_ANIMALS: Mutex<HashMap<i32,AnimalBox>> = Mutex::new(HashMap::new());
}
//simple trait for our animals
trait AnimalExt{
//eat() function requires a mutable reference to another AnimalBox
fn eat(&mut self,pray: &mut AnimalBox);
fn perish(&mut self);
fn energy(&self)->i32;
fn id(&self)->i32;
}
struct Wolf{
id: i32,energy: i32,alive: bool,}
impl AnimalExt for Wolf{
fn id(&self)->i32{
self.id
}
fn eat(&mut self,pray: &mut AnimalBox) {
pray.perish();
self.energy+= pray.energy()
}
fn energy(&self) ->i32 {
self.energy
}
fn perish(&mut self){
self.alive = false;
}
}
impl Wolf{
pub fn new(id: i32)->Self{
Wolf{
id: id,energy: 50,alive: true,}
}
}
struct Cow{
id: i32,}
impl Cow{
pub fn new(id: i32)->Self{
Cow{
id: id,energy: 100,}
}
}
impl AnimalExt for Cow{
fn id(&self)->i32{
self.id
}
fn eat(&mut self,pray: &mut AnimalBox) {
pray.perish();
self.energy+= pray.energy()
}
fn energy(&self) ->i32 {
self.energy
}
fn perish(&mut self){
self.alive = false;
}
}
fn main() {
println!("Hello,world!");
//define our animals
let cow1 = Box::new(Cow::new(1)) as AnimalBox;
let cow2 = Box::new(Cow::new(2)) as AnimalBox;
let wolf1 = Box::new(Wolf::new(3)) as AnimalBox;
let wolf2 = Box::new(Wolf::new(4)) as AnimalBox;
//insert them into the global hashmap
MY_ANIMALS.lock().unwrap().insert(cow1.id(),cow1);
MY_ANIMALS.lock().unwrap().insert(cow2.id(),cow2);
MY_ANIMALS.lock().unwrap().insert(wolf1.id(),wolf1);
MY_ANIMALS.lock().unwrap().insert(wolf2.id(),wolf2);
//getting one animal to eat() another causes a WouldBlock error
match (MY_ANIMALS.try_lock().unwrap().get_mut(&0),MY_ANIMALS.try_lock().unwrap().get_mut(&1)){
(Some(a1),Some(a2))=>{
a1.eat(a2);
}
_=>()
}
}
,这与 lazy_static 的 RefCell
特征要求不兼容。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)