“error: closure may outlive the current function” but it will not outlive it

后端 未结 2 687
南方客
南方客 2021-01-04 10:07

When I try to compile the following code:

fn main() {

    (...)

    let mut should_end = false;

    let mut input = Input::new(ctx);

    input.add_handle         


        
相关标签:
2条回答
  • 2021-01-04 10:52

    The problem is not your closure, but the add_handler method. Fully expanded it would look like this:

    fn add_handler<'a>(&'a mut self, handler: Box<FnMut(i32) + 'static>)
    

    As you can see, there's an implicit 'static bound on the trait object. Obviously we don't want that, so we introduce a second lifetime 'b:

    fn add_handler<'a, 'b: 'a>(&'a mut self, handler: Box<FnMut(i32) + 'b>)
    

    Since you are adding the handler object to the Input::handlers field, that field cannot outlive the scope of the handler object. Thus we also need to limit its lifetime:

    pub struct Input<'a> {
        handlers: Vec<Box<FnMut(i32) + 'a>>,
    }
    

    This again requires the impl to have a lifetime, which we can use in the add_handler method.

    impl<'a> Input<'a> {
        ...
        pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
            self.handlers.push(handler);
        }
    }
    

    Now all that's left is using a Cell to control access to your should_end flag.

    0 讨论(0)
  • 2021-01-04 10:59

    Here is an example of the fixed code:

    use std::cell::Cell;
    
    fn main() {
        let should_end = Cell::new(false);
        let mut input = Input::new();
        input.add_handler(Box::new(|a| {
            match a {
                1 => {
                    should_end.set(true);
                }
                _ => {
                    println!("{} {}", a, should_end.get())
                }
            }
        }));
        let mut fail_safe = 0;
        while !should_end.get() {
            if fail_safe > 20 {break;}
            input.handle();
            fail_safe += 1;
        }
    }
    
    pub struct Input<'a> {
        handlers: Vec<Box<FnMut(i32) + 'a>>,
    }
    
    impl<'a> Input<'a> {
        pub fn new() -> Self {
            Input {handlers: Vec::new()}
        }
        pub fn handle(&mut self) {
            for a in vec![21,0,3,12,1,2] {// it will print the 2, but it won't loop again
                for handler in &mut self.handlers {
                    handler(a);
                }
            }
        }
        pub fn add_handler(&mut self, handler: Box<FnMut(i32) + 'a>) {
            self.handlers.push(handler);
        }
    }
    
    0 讨论(0)
提交回复
热议问题