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

做~自己de王妃 提交于 2019-11-30 18:24:14

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.

Shepmaster

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);
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!