Skip to content

Instantly share code, notes, and snippets.

@matthewjberger
Last active December 29, 2022 14:33
Show Gist options
  • Save matthewjberger/f026c5e95b04e9846decf2541e75c342 to your computer and use it in GitHub Desktop.
Save matthewjberger/f026c5e95b04e9846decf2541e75c342 to your computer and use it in GitHub Desktop.
Rust callback with non-static lifetime
use anyhow::{bail, Result};
use std::sync::{Arc, RwLock};
struct Processor<'a> {
callback: Box<dyn FnMut() -> Result<()> + 'a>,
}
impl<'a> Processor<'a> {
fn set_callback(&mut self, c: impl FnMut() -> Result<()> + 'a) {
self.callback = Box::new(c);
}
fn process_events(&mut self) -> Result<()> {
(self.callback)()
}
}
fn simple_callback() -> Result<()> {
println!("hello");
Ok(())
}
struct MyThing {
val: u32,
}
fn main() -> Result<()> {
let mut p = Processor {
callback: Box::new(simple_callback),
};
p.process_events()?;
// The variables used in the closure are moved
let thing = MyThing { val: 37 };
let ptr = Arc::new(RwLock::new(thing));
let s = "world!".to_string();
let callback2 = move || match ptr.write() {
Ok(mut ptr) => {
ptr.val += 3;
println!("hello {} - {}", s, ptr.val);
Ok(())
}
Err(error) => bail!("{}", error),
};
// this is invalid because the pointer was moved into the closure
// ptr.write().unwrap().val = 100;
p.set_callback(callback2);
p.process_events()?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment