在 Rust 中一次从全局哈希映射访问两个可变引用

问题描述

假设我们有一个由 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 (将#修改为@)