Вот небольшой пример кода, представляющий проблему, с которой я столкнулся в данный момент. CmdMap
хранит некоторые логи c из Trait
типов, которые должны запускаться клавишей String
. Для этой логики c требуется контекст, предоставленный экземпляром Arg
. В этом Arg
экземпляре нам могут понадобиться изменяемые ссылки на некоторые объекты (представленные здесь Printer
).
Вот код:
use std::collections::HashMap;
struct Cmd {}
pub trait Trait<T> {
fn execute(args: T) -> Result<(), String>;
}
impl<'a> Trait<Arg<'a>> for Cmd {
fn execute(arg: Arg) -> Result<(), String> {
arg.printer.print("execute".to_string());
Ok(())
}
}
struct Printer {
name: String,
}
impl Printer {
pub fn print(&mut self, msg: String) {
self.name = "print".to_string();
println!("{}: {}", self.name, msg);
}
}
struct Arg<'a> {
pub printer: &'a mut Printer,
}
type Callback<T> = dyn Fn(T) -> Result<(), String>;
struct CmdMap<T> {
pub map: HashMap<String, Box<Callback<T>>>,
}
impl<T> CmdMap<T> {
pub fn try_execute(&self, name: String, arg: T) {
self.map[&name](arg);
}
}
fn test() {
let mut map: CmdMap<Arg> = CmdMap {
map: HashMap::new(),
};
map.map.insert("test".to_string(), Box::new(Cmd::execute));
let mut printer: Printer = Printer {
name: "".to_string(),
};
loop {
map.try_execute(
"test".to_string(),
Arg {
printer: &mut printer,
},
);
}
}
Компилятор жалуется:
error[E0499]: cannot borrow `printer` as mutable more than once at a time
--> src/lib.rs:57:26
|
47 | map.map.insert("test".to_string(), Box::new(Cmd::execute));
| ---------------------- cast requires that `printer` is borrowed for `'static`
...
57 | printer: &mut printer,
| ^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
...
58 | map.try_execute("test".to_string(), Arg { printer: &mut printer });
| ^^^^^^^^^^^^ mutable borrow starts here in previous iteration of loop
Я не понимаю и почему компилятор жалуется здесь. Первая ошибка cast requires that printer is borrowed for 'static
не имеет смысла для меня, поскольку я храню Fn
типов, которые должны заимствовать printer
только на время их выполнения.
Я что-то упустил?