I am having a hard time solving problems with references and borrowing.
My end goal is that a user can create instance of a bot, add callbacks to it (pairs of (String
, closure)) and then call listen
. When the bot receives a message, it compares the text of the message to the keys in the hashmap of closures. If one of them matches, it calls the corresponding callback closure.
I need to use String
field on instance b
of the struct in the async move
block in the closure passed to b
's method add_closure
and that's the problem.
What I've tried: different smart pointers, it didn't help though.
use futures::Future;
use std::pin::Pin;
struct B {
val: String,
closures: Vec<Box<dyn FnMut() -> Pin<Box<dyn Future<Output = ()>>>>>,
}
impl B {
fn add_closure(&mut self, closure: Box<dyn FnMut() -> Pin<Box<dyn Future<Output = ()>>>>) {
self.closures.push(closure);
}
}
fn main() {
let mut b = B {
val: "test".to_string(),
closures: vec![],
};
b.add_closure(Box::new(|| {
Box::pin(async {
println!("{}", b.val);
})
}));
}
The compiler's error message is huge:
error[E0502]: cannot borrow `b` as mutable because it is also borrowed as immutable
--> src/main.rs:21:5
|
21 | b.add_closure(Box::new(|| {
| ^ - -- immutable borrow occurs here
| ______|_____________|
| | _____|
| ||
22 | || Box::pin(async {
23 | || println!("{}", b.val);
| || - first borrow occurs due to use of `b` in closure
24 | || })
25 | || }));
| ||______-^ mutable borrow occurs here
| |_______|
| cast requires that `b` is borrowed for `'static`
error[E0597]: `b` does not live long enough
--> src/main.rs:23:28
|
21 | b.add_closure(Box::new(|| {
| - -- value captured here
| ___________________|
| |
22 | | Box::pin(async {
23 | | println!("{}", b.val);
| | ^ borrowed value does not live long enough
24 | | })
25 | | }));
| |______- cast requires that `b` is borrowed for `'static`
26 | }
| - `b` dropped here while still borrowed
error: aborting due to 2 previous errors
How to use
What I need to do to get what I wanted to work?