“错误:闭包可能会超过当前函数的寿命"但它不会比它长寿 [英] "error: closure may outlive the current function" but it will not outlive it

查看:100
本文介绍了“错误:闭包可能会超过当前函数的寿命"但它不会比它长寿的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试编译以下代码时:

When I try to compile the following code:

fn main() {

    (...)

    let mut should_end = false;

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

    input.add_handler(Box::new(|evt| {
        match evt {
            &Event::Quit{..} => {
                should_end = true;
            }
            _ => {}
        }
    }));

    while !should_end {
        input.handle();
    }
}

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

impl Input {
    pub fn new() -> Self {
        Input {handlers: Vec::new()}
    }
    pub fn handle(&mut self) {
        for a in vec![21,0,3,12,1] {
            for handler in &mut self.handlers {
                handler(a);
            }
        }
    }
    pub fn add_handler(&mut self, handler: Box<FnMut(i32)>) {
        self.handlers.push(handler);
    }
}

我收到此错误:

error: closure may outlive the current function, but it borrows `should_end`, which is owned by the current function

我不能简单地将move添加到闭包中,因为稍后需要在主循环中使用should_end.我的意思是,我可以,但是由于boolCopy,它只会影响闭包内部的should_end,因此程序会永远循环.

I can't simply add move to the closure, because I need to use should_end later in the main loop. I mean, I can, but since bool is Copy, it will only affect the should_end inside the closure, and thus the program loops forever.

据我了解,由于input是在主函数中创建的,而闭包存储在input中,因此它不可能超过当前函数.有没有办法向Rust表示闭包不会超过main?还是有可能我看不到闭包的寿命超过了main?在后一种情况下,有一种方法可以强制它仅生存到main?

As far as I understand, since input is created in the main function, and the closure is stored in input, it couldn't possibly outlive the current function. Is there a way to express to Rust that the closure won't outlive main? Or is there a possibility that I can't see that the closure will outlive main? In the latter case, it there a way to force it to live only as long as main?

我是否需要重构我处理输入的方式,或者是否可以通过某种方式来完成这项工作.如果需要重构,在哪里可以找到Rust的一个很好的例子?

Do I need to refactor the way I'm handling input, or is there some way I can make this work. If I need to refactor, where can I look to see a good example of this in Rust?

这是简化版本的游戏围栏.我可能在其中犯了一个错误,可能会导致浏览器崩溃.我曾经碰巧遇到过一次,所以要当心.

Here's a playpen of a simplified version. It is possible I made a mistake in it that could crash your browser. I happened to me once, so, beware.

如果需要,我的代码可用.所有相关信息都应位于main.rsinput.rs中.

In case it is needed, the rest of my code is available. All the relevant info should be in either main.rs or input.rs.

推荐答案

问题不是您的关闭,而是add_handler方法.完全扩展后,它看起来像这样:

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>)

如您所见,特征对象上绑定了一个隐式'static.显然我们不想要这样,所以我们引入了第二个生命周期'b:

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>)

由于要将handler对象添加到Input::handlers字段,因此该字段不能超过handler对象的范围.因此,我们还需要限制其寿命:

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>>,
}

这再次要求impl具有生存期,我们可以在add_handler方法中使用它.

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);
    }
}

现在剩下的就是使用Cell来控制对should_end标志的访问.

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

这篇关于“错误:闭包可能会超过当前函数的寿命"但它不会比它长寿的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆